style: 项目重构

1.项目改名为kilostar(千星)
2.后端部分进行大规模重构
3.node功能进行大规模重新设计
This commit is contained in:
2026-05-11 15:29:16 +00:00
parent 2d8571dee3
commit ee9bbbf676
134 changed files with 2190 additions and 2503 deletions
+1 -1
View File
@@ -2,5 +2,5 @@ POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgrespassword
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_DB=pretor
POSTGRES_DB=kilostar
SECRET_KEY=114514
+19 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
# Pretor (执政官)
# KiloStar (千星)
一款基于 Python 的分布式多 Agent 协作系统
@@ -14,14 +14,14 @@
</div>
---
**Pretor** 是一款基于 **Ray** 构建的下一代分布式多 Agent 协作系统。项目采用“中心监管 + 边缘执行”的异构集群模式,通过大参数 MoE 模型进行高层逻辑推理,并协同微调后的轻量化模型高效完成具体任务。借助 **Pydantic-AI** 提供的强类型约束与 FastAPI 异步网关,Pretor 实现了任务从需求拆解、资源调度到自动化执行的全链路闭环,为个人提供可靠的人工智能助手服务。
**KiloStar** 是一款基于 **Ray** 构建的下一代分布式多 Agent 协作系统。项目采用“中心监管 + 边缘执行”的异构集群模式,通过大参数 MoE 模型进行高层逻辑推理,并协同微调后的轻量化模型高效完成具体任务。借助 **Pydantic-AI** 提供的强类型约束与 FastAPI 异步网关,kilostar 实现了任务从需求拆解、资源调度到自动化执行的全链路闭环,为个人提供可靠的人工智能助手服务。
---
## ✨ 核心特性
### 🧠 异构协作体系
- **多智能体集群**:内置主管 (Supervisory)、意识 (Consciousness)、控制 (Control) 三大核心节点,实现比单 Agent 系统更严谨的决策链。
- **多智能体集群**:内置监控 (Regulatory)、意识 (Consciousness)、控制 (Control) 、 生长(Growth)核心节点,实现比单 Agent 系统更严谨的决策链。
- **Worker 动态派生**:根据任务需求动态拉起 Ordinary 或 Skill 类型的 Worker Individual,实现资源的按需分配。
### 🚀 分布式性能保障
@@ -32,14 +32,14 @@
- **强类型契约**:基于 Pydantic-AI 实现 Tool 与 Agent 的接口定义,确保 AI 输出的确定性与安全性。
- **自动化流**:内置工作流引擎 (Workflow Engine),实现从需求发现到自动化执行的闭环。
### 📦 Pretor 生态子项目 (Sub-projects)
### 📦 KiloStar 生态子项目 (Sub-projects)
| 项目名称 | 代号 | 功能定位 | 当前状态 |
|:-----------------------------------------------------------|:--------| :--- | :--- |
| **[pretor-viceroy](https://github.com/zhaoxi826/viceroy)** | **总督** | **资源管理**:负责系统 Skill 的动态安装、元数据解析与全集群分发。 | ✅ 已发布 |
| **pretor-stardomain** | **星域** | **安全沙箱**:为 Agent 自动生成的代码提供轻量化的隔离运行环境,防止逃逸。 | 📅 规划中 |
| **pretor-explorer** | **探索者** | **网页感知**:自动化爬虫引擎,赋予智能体实时互联网信息搜索与内容抓取能力。 | 📅 规划中 |
| **pretor-pioneer** | **先驱者** | **知识增强**:RAG 检索增强引擎,管理私有知识库的向量化、索引与精准检索。 | 📅 规划中 |
| **[kilostar-viceroy](https://github.com/zhaoxi826/viceroy)** | **总督** | **资源管理**:负责系统 Skill 的动态安装、元数据解析与全集群分发。 | ✅ 已发布 |
| **kilostar-stardomain** | **星域** | **安全沙箱**:为 Agent 自动生成的代码提供轻量化的隔离运行环境,防止逃逸。 | 📅 规划中 |
| **kilostar-explorer** | **探索者** | **网页感知**:自动化爬虫引擎,赋予智能体实时互联网信息搜索与内容抓取能力。 | 📅 规划中 |
| **kilostar-pioneer** | **先驱者** | **知识增强**:RAG 检索增强引擎,管理私有知识库的向量化、索引与精准检索。 | 📅 规划中 |
---
## 🚀 快速开始 (Quick Start)
@@ -48,27 +48,27 @@
> 本项目目前处于快速迭代阶段,欢迎提交 Issue 或 Pull Request。
### 方式一:使用 Docker Compose (推荐)
这是部署 **Pretor 应用** 及其配套 **PostgreSQL 数据库** 最简单、最完整的方式。
这是部署 **kilostar 应用** 及其配套 **PostgreSQL 数据库** 最简单、最完整的方式。
1. **准备配置文件**:在本地创建一个目录,并新建 `docker-compose.yml`
```yaml
services:
db:
image: postgres:16-alpine
container_name: pretor_db
container_name: kilostar_db
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgrespassword
POSTGRES_DB: pretor
POSTGRES_DB: kilostar
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d pretor"]
test: ["CMD-SHELL", "pg_isready -U postgres -d kilostar"]
interval: 5s
timeout: 5s
retries: 5
pretor:
image: zhaoxi5699/pretor:v0.1.0alpha
container_name: pretor
kilostar:
image: zhaoxi5699/kilostar:v0.1.0alpha
container_name: kilostar
ports:
- "8000:8000"
- "8265:8265"
@@ -80,7 +80,7 @@
- POSTGRES_PASSWORD=postgrespassword
- POSTGRES_HOST=db
- POSTGRES_PORT=5432
- POSTGRES_DB=pretor
- POSTGRES_DB=kilostar
- SECRET_KEY=changethiskey12345 # 请在生产环境中修改此密钥
```
@@ -93,15 +93,15 @@
1. **启动服务**
```bash
docker run -d \
--name pretor \
--name kilostar \
-p 8000:8000 \
-p 8265:8265 \
-e POSTGRES_HOST=你的数据库IP \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgrespassword \
-e POSTGRES_DB=pretor \
-e POSTGRES_DB=kilostar \
-e SECRET_KEY=your_secret_key \
zhaoxi5699/pretor:v0.1.0alpha
zhaoxi5699/kilostar:v0.1.0alpha
```
## 🔍 访问与验证
+1 -1
View File
@@ -17,7 +17,7 @@
- **分布式 Actor 骨架**:基于 Ray 框架构建了多智能体协作底座,支持节点跨进程通讯与资源调度。
- **全局状态机 (GSM)**:实现了 `GlobalStateMachine` 模块,作为系统的“唯一真相来源”,管理所有 Individual、Skill 和 Provider 的注册信息。
- **核心认知节点**
- `SupervisoryNode`:负责任务拆解与分发。
- `regulatoryNode`:负责任务拆解与分发。
- `ConsciousnessNode`:负责意图识别与语义理解。
- `ControlNode`:负责工作流状态监控与逻辑卡点。
- **异步工作流引擎**:实现 `WorkflowRunningEngine`,支持从数据库自动轮询并异步执行待办任务流。
+3 -3
View File
@@ -6,9 +6,9 @@
#### 功能增加
- [ ] **完善系统插件**: 如 **RAG(检索增强生成)****沙箱** **联网搜索** ,使agent拥有更多的能力适应多样化任务需求
- [ ] **增加MCP功能**: 增加MCP,使得agent可以调用通用工具
- [ ] **完善special_individual** 使得`supervisory_node`等可以调用实现语言生成图像生成等功能
- [ ] **完善supervisory_node**: 实现`supervisory_node`对于工作流状态的访问,实现更方便的检测
- [ ] **对消息平台的对接**: 完善platform,实现对于更多消息平台的对接(如:钉钉微信等),实现在社交软件对`supervisory_node`下达命令
- [ ] **完善special_individual** 使得`regulatory_node`等可以调用实现语言生成图像生成等功能
- [ ] **完善regulatory_node**: 实现`regulatory_node`对于工作流状态的访问,实现更方便的检测
- [ ] **对消息平台的对接**: 完善platform,实现对于更多消息平台的对接(如:钉钉微信等),实现在社交软件对`regulatory_node`下达命令
#### 系统优化
- [ ] **优化workflow逻辑**: 通过**graph**等设计实现更优秀的工作流调度
+6 -6
View File
@@ -3,22 +3,22 @@ version: '3.8'
services:
db:
image: postgres:16-alpine
container_name: pretor_db
container_name: kilostar_db
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgrespassword
POSTGRES_DB: pretor
POSTGRES_DB: kilostar
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d pretor"]
test: ["CMD-SHELL", "pg_isready -U postgres -d kilostar"]
interval: 5s
timeout: 5s
retries: 5
pretor:
kilostar:
build: .
container_name: pretor
container_name: kilostar
ports:
- "8000:8000"
- "8265:8265"
@@ -30,6 +30,6 @@ services:
- POSTGRES_PASSWORD=postgrespassword
- POSTGRES_HOST=db
- POSTGRES_PORT=5432
- POSTGRES_DB=pretor
- POSTGRES_DB=kilostar
- SECRET_KEY=changethiskey12345
+9 -9
View File
@@ -1,21 +1,21 @@
## Pretor项目
## kilostar项目
#### 简介
**Pretor**是一款python开发,实现将小模型进行微调后整理为一个大型集群,从而实现低算力情况下高复杂度任务的实现。
**kilostar**是一款python开发,实现将小模型进行微调后整理为一个大型集群,从而实现低算力情况下高复杂度任务的实现。
系统模型分为以下部分:
- **监管节点**:负责基本交流和任务分流
- **监管节点**:负责基本交流和简单任务执行
- **管控节点**:负责调度系统资源;
- **意识节点**:负责复杂任务的处理;
- **生长节点**:负责获取资源并且将基础模型训练为特化模型
- **生长节点**:负责扩张集群和子个体
- **特殊子个体**:与外界交互的模型,如embedding模型,tts模型等;
- **专家子个体**:携带有专业skill的agent对象;
- **基础子个体**:普通的agent对象;
---
#### 项目介绍
**Pretor** 是一款基于分布式计算平台 **Ray** 和 agent开发框架**pydantic-AI** 开发的多智能体协作平台,通过多智能体的协作和任务拆解,实现复杂任务的高质量完成。
**kilostar** 是一款基于分布式计算平台 **Ray** 和 agent开发框架**pydantic-AI** 开发的多智能体协作平台,通过多智能体的协作和任务拆解,实现复杂任务的高质量完成。
**Pretor**使用 **python**著名的高性能后端框架 **Fastapi** 来作为整个系统对用户暴露接口的网关。在**Pretor**运行过程中,用户通过发送请求至fastapi从而包装为 `PretorEvent`对象,并且发往`supervisory_node`,由**supervisory_node**进行简单的意图判断,如果判断用户只是简单交流比如聊天等,**supervisory_node**会直接对用户进行回复结束事件。
,如果判断用户想要完成复杂的任务,**supervisory_node**会选择将从`workflow_template(工作流模板)`中选择一个或者不选择,然后将event挂到`全局状态机`实现追溯方便并发往`Workflow_Running_Engine`的异步队列,被协程对象取走后,由**consciousness_node**创建为`PretorWorkflow`对象,挂载到实例化的`WorkflowEngine`进行执行。完成任务后返回给用户。
**kilostar**使用 **python**著名的高性能后端框架 **Fastapi** 来作为整个系统对用户暴露接口的网关。在**kilostar**运行过程中,用户通过发送请求至fastapi从而包装为 `kilostarEvent`对象,并且发往`regulatory_node`,由**regulatory_node**进行简单的意图判断,如果判断用户只是简单交流比如聊天等,**regulatory_node**会直接对用户进行回复结束事件。
,如果判断用户想要完成复杂的任务,**regulatory_node**会选择将从`workflow_template(工作流模板)`中选择一个或者不选择,然后将event挂到`全局状态机`实现追溯方便并发往`Workflow_Running_Engine`的异步队列,被协程对象取走后,由**consciousness_node**创建为`kilostarWorkflow`对象,挂载到实例化的`WorkflowEngine`进行执行。完成任务后返回给用户。
---
#### 技术架构背景
@@ -27,8 +27,8 @@
---
#### 项目背景
###### 1.多智能体架构的需求
随着任务复杂度的提升,单一**Agent**一定程度上以及满足不了人们对于人工智能完成复杂任务的需求。模仿人类社会中的团队合作,Pretor以**Ray**作为底座,从而实现一种多智能体协作的设计。
随着任务复杂度的提升,单一**Agent**一定程度上以及满足不了人们对于人工智能完成复杂任务的需求。模仿人类社会中的团队合作,kilostar以**Ray**作为底座,从而实现一种多智能体协作的设计。
###### 2.对于大语言模型输出内容约束的需求
LLM 输出的非结构化文本在多智能体交互中极易崩溃。所以,**Pretor**没有选择如**LangChain**这种老牌智能体开发框架,而是选择了新兴的**pydanticAI**这种强约束框架,使得多智能体协作避免黑盒化。
LLM 输出的非结构化文本在多智能体交互中极易崩溃。所以,**kilostar**没有选择如**LangChain**这种老牌智能体开发框架,而是选择了新兴的**pydanticAI**这种强约束框架,使得多智能体协作避免黑盒化。
**PydanticAI**是一款基于**Pydantic**的智能体开发框架,**Pydantic**是**python**中著名的数据类型约束库,**Pydantic**官方通过**Pydantic**的强约束,实现了对于LLM的生成约束。
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>pretor-dashboard</title>
<title>kilostar-dashboard</title>
</head>
<body>
<div id="root"></div>
+2 -2
View File
@@ -1,11 +1,11 @@
{
"name": "pretor-dashboard",
"name": "kilostar-dashboard",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pretor-dashboard",
"name": "kilostar-dashboard",
"version": "0.0.0",
"dependencies": {
"@xyflow/react": "^12.10.2",
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "pretor-dashboard",
"name": "kilostar-dashboard",
"private": true,
"version": "0.0.0",
"type": "module",
@@ -50,7 +50,7 @@ export function WorkerIndividualSettings() {
setAvailableSkills(Object.keys(skillsRes.data.skills || {}));
const sysNodesData = sysRes.data.system_nodes || [];
const defaultSysNodes = ['supervisory_node', 'consciousness_node', 'control_node'];
const defaultSysNodes = ['regulatory_node', 'consciousness_node', 'control_node'];
const providersList = Object.values(provRes.data.provider_list || {}) as Provider[];
const defaultProvider = providersList.length > 0 ? providersList[0].provider_title : '';
+3 -3
View File
@@ -136,7 +136,7 @@ export function ChatPanel({ chatSessions, setChatSessions, activeSessionId, setA
return (
<div className="flex-1 flex flex-col bg-white overflow-hidden items-center justify-center">
<Activity size={48} className="text-slate-300 mb-4" />
<h2 className="text-xl font-semibold text-slate-600">Pretor Assistant</h2>
<h2 className="text-xl font-semibold text-slate-600">kilostar Assistant</h2>
<p className="text-slate-400 mt-2">Select a chat history or create a new one to start.</p>
<button
onClick={() => {
@@ -147,7 +147,7 @@ export function ChatPanel({ chatSessions, setChatSessions, activeSessionId, setA
{
id: Date.now().toString(),
role: 'assistant',
content: 'Hello! I am Pretor Assistant. How can I help you today?',
content: 'Hello! I am kilostar Assistant. How can I help you today?',
timestamp: Date.now(),
},
],
@@ -251,7 +251,7 @@ export function ChatPanel({ chatSessions, setChatSessions, activeSessionId, setA
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSendMessage()}
placeholder="Ask Pretor to do something..."
placeholder="Ask kilostar to do something..."
className="w-full bg-slate-50 border border-slate-200 text-sm rounded-2xl pl-12 pr-12 py-3.5 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-400 transition-all"
/>
<button
+1 -1
View File
@@ -69,7 +69,7 @@ export function LeftPanel({
{
id: Date.now().toString(),
role: 'assistant',
content: 'Hello! I am Pretor Assistant. How can I help you today?',
content: 'Hello! I am kilostar Assistant. How can I help you today?',
timestamp: Date.now(),
},
],
+1 -1
View File
@@ -13,7 +13,7 @@ export function TopBar({ mode, setMode, showSettings, setShowSettings }: TopBarP
{/* Left: Logo */}
<div className="flex items-center space-x-2 font-bold text-xl tracking-tight text-blue-900">
<BrainCircuit className="text-blue-600" size={24} />
<span>Pretor</span>
<span>kilostar</span>
</div>
{/* Right Container: Mode Toggle Switch + Settings */}
@@ -17,10 +17,10 @@ from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.openai import OpenAIProvider
from pydantic_ai.providers.anthropic import AnthropicProvider
from pretor.adapter.model_adapter.deepseek_reasoner import DeepSeekReasonerAgent
from pretor.core.global_state_machine.model_provider import Provider
from pretor.utils.agent_model import ResponseModel, DepsModel
from pretor.utils.error import ModelNotExistError
from kilostar.adapter.model_adapter.deepseek_reasoner import DeepSeekReasonerAgent
from kilostar.core.global_state_machine.model_provider import Provider
from kilostar.utils.agent_model import ResponseModel, DepsModel
from kilostar.utils.error import ModelNotExistError
class AgentFactory:
@@ -27,7 +27,7 @@ from .platform.frontend import client_router
from .provider import provider_router
from .resource import resource_router
from .workflow import workflow_router
from pretor.utils.error import (
from kilostar.utils.error import (
DemandError,
ModelNotExistError,
UserError,
@@ -132,14 +132,14 @@ if os.path.exists(frontend_dir):
else:
import logging
logging.getLogger("pretor").warning(
logging.getLogger("kilostar").warning(
f"Frontend dist folder not found at {frontend_dir}. Skipping frontend mount."
)
@serve.deployment
@serve.ingress(app)
class PretorGateway:
class kilostarGateway:
gateway: Dict[str, WebSocket]
def __init__(self):
@@ -14,15 +14,15 @@
from typing import Union
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.ray_hook import ray_actor_hook
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from pretor.utils.access import Accessor, TokenData
from pretor.core.postgres_database.table import AgentType
from kilostar.utils.access import Accessor, TokenData
from kilostar.core.postgres_database.model import AgentType
from fastapi import HTTPException
from typing import Optional, List, Dict
from pretor.utils.check_user.role_check import RoleChecker
from pretor.core.postgres_database.table import UserAuthority
from kilostar.utils.check_user.role_check import RoleChecker
from kilostar.core.postgres_database.model import UserAuthority
agent_router = APIRouter(prefix="/api/v1/agent", tags=["agent"])
@@ -86,8 +86,8 @@ async def load_agent(
# Load agent into state machine
match agent_register.individual_name:
case "supervisory_node":
node = ray_actor_hook("supervisory_node").supervisory_node
case "regulatory_node":
node = ray_actor_hook("regulatory_node").regulatory_node
await node.create_agent.remote(
global_state_machine,
agent_register.provider_title,
+5 -5
View File
@@ -15,12 +15,12 @@
from fastapi import APIRouter
from fastapi import Depends
from pydantic import BaseModel
from pretor.utils.access import Accessor, TokenData
from kilostar.utils.access import Accessor, TokenData
from fastapi.concurrency import run_in_threadpool
from pretor.utils.ray_hook import ray_actor_hook
from pretor.utils.check_user.role_check import RoleChecker
from pretor.core.postgres_database.table import UserAuthority
from pretor.utils.error import UserNotExistError
from kilostar.utils.ray_hook import ray_actor_hook
from kilostar.utils.check_user.role_check import RoleChecker
from kilostar.core.postgres_database.model import UserAuthority
from kilostar.utils.error import UserNotExistError
auth_router = APIRouter(prefix="/api/v1/auth", tags=["auth"])
@@ -16,13 +16,13 @@ import datetime
from pydantic import BaseModel, Field, ConfigDict
from ulid import ULID
from typing import Any, Dict
from pretor.core.workflow.workflow import PretorWorkflow
from kilostar.core.workflow_running_engine.workflow import kilostarWorkflow
import asyncio
class PretorEvent(BaseModel):
"""PretorEvent 核心组件类。
这是一个领域数据模型或功能封装类承载了 PretorEvent 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
class kilostarEvent(BaseModel):
"""kilostarEvent 核心组件类。
这是一个领域数据模型或功能封装类承载了 kilostarEvent 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
model_config = ConfigDict(arbitrary_types_allowed=True)
trace_id: str = Field(
@@ -43,7 +43,7 @@ class PretorEvent(BaseModel):
context: Dict[str, Any] = Field(
default_factory=dict, description="事件上下文内容,可包含工作流模板等信息"
)
workflow: PretorWorkflow | None = Field(default=None, description="工作流")
workflow: kilostarWorkflow | None = Field(default=None, description="工作流")
pending_queue: asyncio.Queue[str] | None = Field(
default=None, description="待处理队列"
)
@@ -14,12 +14,12 @@
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File
from pydantic import BaseModel
from pretor.utils.access import Accessor, TokenData
from pretor.api.platform.event import PretorEvent
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.access import Accessor, TokenData
from kilostar.api.platform.event import kilostarEvent
from kilostar.utils.ray_hook import ray_actor_hook
import os
import anyio
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
logger = get_logger("frontend")
@@ -43,14 +43,14 @@ async def create_message(
Returns: : 序列化后的标准网络响应模型如包含业务状态码成功标志及对应的数据载荷 Data"""
logger.info("收到消息,来源:客户端")
logger.debug(f"消息内容:{message.message}")
event = PretorEvent(
event = kilostarEvent(
platform="client",
user_id=str(token_data.user_id),
user_name=token_data.username,
message=message.message,
)
supervisory_node = ray_actor_hook("supervisory_node").supervisory_node
message = await supervisory_node.working.remote(event)
regulatory_node = ray_actor_hook("regulatory_node").regulatory_node
message = await regulatory_node.working.remote(event)
if message.startswith("任务已创建"):
return {"message": f"{event.trace_id}\n\n{message}"}
elif message == "未知相应类型":
@@ -15,12 +15,12 @@
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from typing import Literal
from pretor.utils.access import TokenData, Accessor
from pretor.utils.check_user.role_check import RoleChecker
from pretor.core.postgres_database.table import UserAuthority
from kilostar.utils.access import TokenData, Accessor
from kilostar.utils.check_user.role_check import RoleChecker
from kilostar.core.postgres_database.model import UserAuthority
from typing import Dict
from pretor.core.global_state_machine.model_provider.base_provider import Provider
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.core.global_state_machine.model_provider.base_provider import Provider
from kilostar.utils.ray_hook import ray_actor_hook
provider_router = APIRouter(prefix="/api/v1/provider", tags=["provider"])
@@ -14,11 +14,11 @@
from pydantic import BaseModel
import viceroy
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.ray_hook import ray_actor_hook
from fastapi import APIRouter, Depends
from pretor.utils.access import TokenData
from pretor.utils.check_user.role_check import RoleChecker
from pretor.core.postgres_database.table import UserAuthority
from kilostar.utils.access import TokenData
from kilostar.utils.check_user.role_check import RoleChecker
from kilostar.core.postgres_database.model import UserAuthority
resource_router = APIRouter(prefix="/api/v1/resource")
@@ -13,7 +13,7 @@
# limitations under the License.
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.ray_hook import ray_actor_hook
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import StreamingResponse
import asyncio
@@ -0,0 +1,3 @@
from kilostar.core.global_state_machine.global_state_machine import GlobalStateMachine
__all__ = ["GlobalStateMachine"]
@@ -13,11 +13,11 @@
# limitations under the License.
import ray
from pretor.core.global_state_machine.provider_manager import ProviderManager
from pretor.core.global_state_machine.tool_manager import GlobalToolManager
from pretor.core.postgres_database import PostgresDatabase
from pretor.core.global_state_machine.skill_manager import GlobalSkillManager
from pretor.core.global_state_machine.individual_manager import GlobalIndividualManager
from kilostar.core.global_state_machine.provider_manager import ProviderManager
from kilostar.core.global_state_machine.tool_manager import GlobalToolManager
from kilostar.core.postgres_database import PostgresDatabase
from kilostar.core.global_state_machine.skill_manager import GlobalSkillManager
from kilostar.core.global_state_machine.individual_manager import GlobalIndividualManager
@ray.remote
@@ -13,7 +13,7 @@
# limitations under the License.
from typing import Dict, Any
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
logger = get_logger("individual_manager")
@@ -12,17 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.global_state_machine.model_provider.base_provider import (
from kilostar.core.global_state_machine.model_provider.base_provider import (
Provider,
ProviderArgs,
)
from pretor.core.global_state_machine.model_provider.openai_provider import (
from kilostar.core.global_state_machine.model_provider.openai_provider import (
OpenAIProvider,
)
from pretor.core.global_state_machine.model_provider.claude_provider import (
from kilostar.core.global_state_machine.model_provider.claude_provider import (
ClaudeProvider,
)
from pretor.core.global_state_machine.model_provider.deepseek_provider import (
from kilostar.core.global_state_machine.model_provider.deepseek_provider import (
DeepseekProvider,
)
@@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.utils.retry import retry_on_retryable_error
from kilostar.utils.retry import retry_on_retryable_error
from pretor.core.global_state_machine.model_provider.base_provider import (
from kilostar.core.global_state_machine.model_provider.base_provider import (
BaseProvider,
Provider,
ProviderArgs,
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.utils.retry import retry_on_retryable_error
from pretor.core.global_state_machine.model_provider.base_provider import (
from kilostar.utils.retry import retry_on_retryable_error
from kilostar.core.global_state_machine.model_provider.base_provider import (
BaseProvider,
Provider,
ProviderArgs,
@@ -67,7 +67,7 @@ class DeepseekProvider(BaseProvider):
model_ids = [m["id"] for m in raw_models]
return sorted(model_ids)
except httpx.RequestError as e:
from pretor.utils.error import RetryableError
from kilostar.utils.error import RetryableError
print(f"[{provider_args.provider_title}] 网络请求异常: {e}")
raise RetryableError(
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.utils.retry import retry_on_retryable_error
from pretor.core.global_state_machine.model_provider.base_provider import (
from kilostar.utils.retry import retry_on_retryable_error
from kilostar.core.global_state_machine.model_provider.base_provider import (
BaseProvider,
Provider,
ProviderArgs,
@@ -67,7 +67,7 @@ class OpenAIProvider(BaseProvider):
model_ids = [m["id"] for m in raw_models]
return sorted(model_ids)
except httpx.RequestError as e:
from pretor.utils.error import RetryableError
from kilostar.utils.error import RetryableError
print(f"[{provider_args.provider_title}] 网络请求异常: {e}")
raise RetryableError(
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.global_state_machine.model_provider import (
from kilostar.core.global_state_machine.model_provider import (
Provider,
OpenAIProvider,
ClaudeProvider,
@@ -64,8 +64,8 @@ class ProviderManager:
接收构建参数执行必要的数据校验与默认值填充后将新记录安全地写入底层存储或系统注册表中
Args: provider_type: 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 provider_type 实例 provider_title: 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 provider_title 实例 provider_url: 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 provider_url 实例 provider_apikey: 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 provider_apikey 实例 provider_owner: 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 provider_owner 实例 postgres_database: 从客户端传递过来或由上游组件生成的核心业务数据体通常需要进一步的清洗和结构化解析
Returns: (None): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
from pretor.core.global_state_machine.model_provider import ProviderArgs
from pretor.utils.logger import get_logger
from kilostar.core.global_state_machine.model_provider import ProviderArgs
from kilostar.utils.logger import get_logger
logger = get_logger("provider_manager")
import httpx
@@ -98,7 +98,7 @@ class ProviderManager:
logger.info(f"已添加适配器{provider_title}")
except httpx.RequestError as e:
from pretor.utils.error import RetryableError
from kilostar.utils.error import RetryableError
logger.warning(f"[{provider_args.provider_title}] 网络请求异常: {e}")
raise RetryableError(
@@ -16,9 +16,9 @@ import pathlib
import importlib
import inspect
from collections import defaultdict
from pretor.plugin.tool_plugin.base_tool import BaseToolData
from kilostar.plugin.tool_plugin.base_tool import BaseToolData
from typing import Dict, Type
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
logger = get_logger("tool_manager")
@@ -41,7 +41,7 @@ class GlobalToolManager:
for item in tool_plugin_dir.iterdir():
if item.is_dir() and not item.name.startswith("__"):
plugin_name = item.name
module_name = f"pretor.plugin.tool_plugin.{plugin_name}"
module_name = f"kilostar.plugin.tool_plugin.{plugin_name}"
try:
module = importlib.import_module(module_name)
@@ -0,0 +1,5 @@
from kilostar.core.global_workflow_manager.global_workflow_manager import (
GlobalWorkflowManager,
)
__all__ = ["GlobalWorkflowManager"]
@@ -1,16 +1,16 @@
import ray
import asyncio
from typing import Dict
from pretor.api.platform.event import PretorEvent
from pretor.core.workflow.workflow import PretorWorkflow
from pretor.utils.ray_hook import ray_actor_hook
from pretor.utils.logger import get_logger
from kilostar.api.platform.event import kilostarEvent
from kilostar.core.workflow_running_engine.workflow import kilostarWorkflow
from kilostar.utils.ray_hook import ray_actor_hook
from kilostar.utils.logger import get_logger
@ray.remote
class GlobalWorkflowManager:
def __init__(self):
self.event_dict: Dict[str, PretorEvent] = {}
self.event_dict: Dict[str, kilostarEvent] = {}
self.event_object_refs: Dict[str, ray.ObjectRef] = {}
self.postgres_database = None
self.logger = get_logger("GlobalWorkflowManager")
@@ -23,7 +23,7 @@ class GlobalWorkflowManager:
records = await self.postgres_database.get_all_events.remote()
for record in records:
try:
event = PretorEvent.model_validate_json(record.event_data_json)
event = kilostarEvent.model_validate_json(record.event_data_json)
event.pending_queue = asyncio.Queue()
event.receive_queue = asyncio.Queue()
self.event_dict[event.trace_id] = event
@@ -65,7 +65,7 @@ class GlobalWorkflowManager:
except Exception as e:
self.logger.error(f"Failed to fetch events from database: {e}")
async def _upsert_event_to_db(self, event: PretorEvent):
async def _upsert_event_to_db(self, event: kilostarEvent):
try:
# Create a copy and remove non-serializable queues
event_copy = event.model_copy()
@@ -82,7 +82,7 @@ class GlobalWorkflowManager:
f"Failed to upsert event {event.trace_id} to database: {e}"
)
async def add_event(self, event: PretorEvent) -> None:
async def add_event(self, event: kilostarEvent) -> None:
event.pending_queue = asyncio.Queue()
event.receive_queue = asyncio.Queue()
self.event_dict[event.trace_id] = event
@@ -98,7 +98,7 @@ class GlobalWorkflowManager:
except Exception as e:
self.logger.error(f"Failed to delete event {trace_id} from database: {e}")
async def get_event(self, trace_id: str) -> PretorEvent | None:
async def get_event(self, trace_id: str) -> kilostarEvent | None:
# First check memory dict
if trace_id in self.event_dict:
return self.event_dict[trace_id]
@@ -107,7 +107,7 @@ class GlobalWorkflowManager:
if trace_id in self.event_object_refs:
try:
event_json = ray.get(self.event_object_refs[trace_id])
return PretorEvent.model_validate_json(event_json)
return kilostarEvent.model_validate_json(event_json)
except Exception as e:
self.logger.warning(
f"Failed to fetch event from cache for trace {trace_id}: {e}"
@@ -117,7 +117,7 @@ class GlobalWorkflowManager:
try:
record = await self.postgres_database.get_event.remote(trace_id)
if record:
event = PretorEvent.model_validate_json(record.event_data_json)
event = kilostarEvent.model_validate_json(record.event_data_json)
# Restore to memory dict with missing transient queues
event.pending_queue = asyncio.Queue()
@@ -145,12 +145,12 @@ class GlobalWorkflowManager:
self.event_dict[trace_id].attachment = attachment
await self._upsert_event_to_db(self.event_dict[trace_id])
async def update_workflow(self, trace_id: str, workflow: PretorWorkflow) -> None:
async def update_workflow(self, trace_id: str, workflow: kilostarWorkflow) -> None:
if trace_id in self.event_dict:
self.event_dict[trace_id].workflow = workflow
await self._upsert_event_to_db(self.event_dict[trace_id])
async def get_workflow(self, trace_id: str) -> PretorWorkflow | None:
async def get_workflow(self, trace_id: str) -> kilostarWorkflow | None:
event = await self.get_event(trace_id)
return event.workflow if event else None
@@ -163,7 +163,7 @@ class GlobalWorkflowManager:
records = await self.postgres_database.get_all_events.remote()
for record in records:
try:
event = PretorEvent.model_validate_json(record.event_data_json)
event = kilostarEvent.model_validate_json(record.event_data_json)
workflow_title = event.workflow.title if event.workflow else None
workflow_status = (
event.workflow.status.status
@@ -15,19 +15,19 @@
import ray
from typing import Union, overload
from pretor.core.individual.consciousness_node.template import (
from kilostar.core.individual.consciousness_node.template import (
ConsciousnessNodeDeps,
ForSupervisoryNode,
ForregulatoryNode,
ForWorkflow,
ForWorkflowEngine,
ForWorkflowInput,
ForSupervisoryInput,
ForregulatoryInput,
ForWorkflowEngineInput,
)
from pydantic_ai import Agent, RunContext
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider.base_provider import Provider
from pretor.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.base_provider import Provider
from kilostar.adapter.model_adapter.agent_factory import AgentFactory
@ray.remote
@@ -36,7 +36,7 @@ class ConsciousnessNode:
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
def __init__(self) -> None:
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
self.logger = get_logger("consciousness_node")
self.agent: None | Agent = None
@@ -62,16 +62,16 @@ class ConsciousnessNode:
无返回
"""
system_prompt: str = (
"你叫Pretor,是一个多智能体AI助手系统中的【意识节点 (Consciousness Node)】。\n"
"你叫kilostar,是一个多智能体AI助手系统中的【意识节点 (Consciousness Node)】。\n"
"你是系统的'高级规划师''架构师',负责处理监控节点分配过来的复杂任务。\n"
"你的主要工作场景包括:\n"
"1. 拆解任务 (Workflow Generation):结合用户的原始命令和提供的模板,生成严谨、可执行的工作流 (PretorWorkflow),并将其输出为 ForWorkflowEngine 格式。拆解时步骤应清晰连贯。\n"
"1. 拆解任务 (Workflow Generation):结合用户的原始命令和提供的模板,生成严谨、可执行的工作流 (kilostarWorkflow),并将其输出为 ForWorkflowEngine 格式。拆解时步骤应清晰连贯。\n"
"2. 中途指导 (Workflow Execution):在工作流执行中,如果某一步骤指派给你,你需要对控制节点的结果进行分析或提供下一步的指导,输出 ForWorkflow 格式。\n"
"3. 总结报告 (Supervisory Report):在整个工作流执行完毕后,你需要对整体流程、各个控制节点的执行情况进行审查,并生成一份技术性的总结报告,输出 ForSupervisoryNode 格式。\n"
"3. 总结报告 (regulatory Report):在整个工作流执行完毕后,你需要对整体流程、各个控制节点的执行情况进行审查,并生成一份技术性的总结报告,输出 ForregulatoryNode 格式。\n"
"请确保所有的思考和生成过程符合逻辑,严密且高质量。"
)
output_type = Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]
from pretor.utils.get_tool import load_tools_from_list
output_type = Union[ForregulatoryNode, ForWorkflow, ForWorkflowEngine]
from kilostar.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
@@ -111,15 +111,15 @@ class ConsciousnessNode:
async def working(
self,
payload: Union[ForWorkflowEngineInput, ForWorkflowInput, ForSupervisoryInput],
) -> Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]:
payload: Union[ForWorkflowEngineInput, ForWorkflowInput, ForregulatoryInput],
) -> Union[ForWorkflowEngine, ForWorkflow, ForregulatoryNode, None]:
"""执行与 working 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑确保操作能够在事务上下文中被原子且一致地执行
Args: payload (Union[ForWorkflowEngineInput, ForWorkflowInput, ForSupervisoryInput]): 从客户端传递过来或由上游组件生成的核心业务数据体通常需要进一步的清洗和结构化解析
Returns: (Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
Args: payload (Union[ForWorkflowEngineInput, ForWorkflowInput, ForregulatoryInput]): 从客户端传递过来或由上游组件生成的核心业务数据体通常需要进一步的清洗和结构化解析
Returns: (Union[ForWorkflowEngine, ForWorkflow, ForregulatoryNode, None]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
try:
result = await self._run(payload)
if isinstance(result, (ForWorkflowEngine, ForWorkflow, ForSupervisoryNode)):
if isinstance(result, (ForWorkflowEngine, ForWorkflow, ForregulatoryNode)):
return result
else:
self.logger.error(
@@ -134,7 +134,7 @@ class ConsciousnessNode:
async def _run(self, payload: ForWorkflowEngineInput) -> ForWorkflowEngine:
"""
_run方法
该分支应当在supervisory_node简单处理用户命令后工作流创建前调用
该分支应当在regulatory_node简单处理用户命令后工作流创建前调用
Args:
payload: 应当包含原始命令和可用技能等信息
@@ -157,7 +157,7 @@ class ConsciousnessNode:
pass
@overload
async def _run(self, payload: ForSupervisoryInput) -> ForSupervisoryNode:
async def _run(self, payload: ForregulatoryInput) -> ForregulatoryNode:
"""
_run方法
该分支应当在workflow运行完全结束后由WorkflowEngine进行调用
@@ -165,18 +165,18 @@ class ConsciousnessNode:
payload: 应当包含整个Workflow的情况
Returns:
ForSupervisory对象作为ConsciousnessNode对于全工作流的技术性总结返回给SupervisoryNode
Forregulatory对象作为ConsciousnessNode对于全工作流的技术性总结返回给regulatoryNode
"""
pass
async def _run(
self,
payload: Union[ForSupervisoryInput, ForWorkflowInput, ForWorkflowEngineInput],
) -> Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]:
payload: Union[ForregulatoryInput, ForWorkflowInput, ForWorkflowEngineInput],
) -> Union[ForregulatoryNode, ForWorkflow, ForWorkflowEngine]:
"""执行与 run 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑确保操作能够在事务上下文中被原子且一致地执行
Args: payload (Union[ForSupervisoryInput, ForWorkflowInput, ForWorkflowEngineInput]): 从客户端传递过来或由上游组件生成的核心业务数据体通常需要进一步的清洗和结构化解析
Returns: (Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
Args: payload (Union[ForregulatoryInput, ForWorkflowInput, ForWorkflowEngineInput]): 从客户端传递过来或由上游组件生成的核心业务数据体通常需要进一步的清洗和结构化解析
Returns: (Union[ForregulatoryNode, ForWorkflow, ForWorkflowEngine]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
try:
self.agent.retries = 3
if isinstance(payload, ForWorkflowEngineInput):
@@ -204,7 +204,7 @@ class ConsciousnessNode:
)
return result.output
elif isinstance(payload, ForSupervisoryInput):
elif isinstance(payload, ForregulatoryInput):
deps = ConsciousnessNodeDeps(
original_command=payload.original_command,
command="对于工作流整体执行结果进行检查,并且生成一份专业的技术性总结报告",
@@ -13,8 +13,8 @@
# limitations under the License.
from pretor.core.workflow.workflow import PretorWorkflow, WorkStep
from pretor.utils.agent_model import ResponseModel, DepsModel, InputModel
from kilostar.core.workflow_running_engine.workflow import kilostarWorkflow, WorkStep
from kilostar.utils.agent_model import ResponseModel, DepsModel, InputModel
from pydantic import Field
@@ -28,7 +28,7 @@ class ConsciousnessNodeResponse(ResponseModel):
class ForWorkflowEngine(ConsciousnessNodeResponse):
"""生成workflow并放入WorkflowEngine"""
workflow: PretorWorkflow = Field(
workflow: kilostarWorkflow = Field(
..., description="生成好的符合规范的完整工作流对象。"
)
reasoning: str = Field(..., description="生成此工作流的原因和思路简述。")
@@ -40,8 +40,8 @@ class ForWorkflow(ConsciousnessNodeResponse):
output: str = Field(..., description="对当前工作流步骤的具体处理结果或指导意见。")
class ForSupervisoryNode(ConsciousnessNodeResponse):
"""工作流完成后进行校验并返回给SupervisoryNode"""
class ForregulatoryNode(ConsciousnessNodeResponse):
"""工作流完成后进行校验并返回给regulatoryNode"""
output: str = Field(
..., description="为监控节点提供的全工作流执行情况的技术性总结报告。"
@@ -80,9 +80,9 @@ class ForWorkflowInput(ConsciousnessNodeInput):
original_command: str
class ForSupervisoryInput(ConsciousnessNodeInput):
"""ForSupervisoryInput 核心组件类。
这是一个领域数据模型或功能封装类承载了 ForSupervisoryInput 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
class ForregulatoryInput(ConsciousnessNodeInput):
"""ForregulatoryInput 核心组件类。
这是一个领域数据模型或功能封装类承载了 ForregulatoryInput 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
workflow: PretorWorkflow
workflow: kilostarWorkflow
original_command: str
@@ -14,10 +14,10 @@
import ray
from pydantic_ai import Agent, RunContext
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider.base_provider import Provider
from pretor.adapter.model_adapter.agent_factory import AgentFactory
from pretor.core.individual.control_node.template import (
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
from kilostar.core.individual.control_node.template import (
ForWorkflow,
ForWorkflowInput,
ControlNodeDeps,
@@ -30,7 +30,7 @@ class ControlNode:
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
def __init__(self):
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
self.logger = get_logger("control_node")
self.agent: Agent | None = None
@@ -56,7 +56,7 @@ class ControlNode:
无返回
"""
system_prompt: str = (
"你叫Pretor,是一个多智能体AI助手系统中的【控制节点 (Control Node)】。\n"
"你叫kilostar,是一个多智能体AI助手系统中的【控制节点 (Control Node)】。\n"
"你是系统的'执行者''车间主任',专门负责执行工作流中分配给你的具体子任务。\n"
"你的工作职责是:\n"
"1. 仔细分析分配给你的工作流步骤 (workflow_step) 的目标和要求。\n"
@@ -65,7 +65,7 @@ class ControlNode:
"请注意:你的输出应当具体、实用,直接提供任务所要求的结果,不要做过多无关的寒暄。"
)
output_type = ForWorkflow
from pretor.utils.get_tool import load_tools_from_list
from kilostar.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
@@ -14,8 +14,8 @@
from pydantic import Field
from pretor.core.workflow.workflow import WorkStep
from pretor.utils.agent_model import ResponseModel, InputModel, DepsModel
from kilostar.core.workflow_running_engine.workflow import WorkStep
from kilostar.utils.agent_model import ResponseModel, InputModel, DepsModel
class ControlNodeResponse(ResponseModel):
@@ -12,3 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from .regulatory_node import regulatoryNode
__all__ = ["regulatoryNode"]
@@ -15,29 +15,29 @@
import datetime
import ray
from typing import Union, overload
from pretor.api.platform.event import PretorEvent
from pretor.adapter.model_adapter.agent_factory import AgentFactory
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider import Provider
from pretor.core.individual.supervisory_node.template import (
from kilostar.api.platform.event import kilostarEvent
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
from kilostar.core.individual.regulatory_node.template import (
ForConsciousnessNode,
ForUser,
SupervisoryNodeDeps,
regulatoryNodeDeps,
TerminationMessage,
)
from pydantic_ai import RunContext, Agent
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.ray_hook import ray_actor_hook
@ray.remote
class SupervisoryNode:
"""SupervisoryNode 核心组件类。
class RegulatoryNode:
"""regulatoryNode 核心组件类。
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
def __init__(self) -> None:
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
self.logger = get_logger("supervisory_node")
self.logger = get_logger("regulatory_node")
self.agent: None | Agent = None
async def create_agent(
@@ -48,7 +48,7 @@ class SupervisoryNode:
tools_list: list[str] = None,
) -> None:
"""
create_agent方法将agent对象装配到SupervisoryNode的属性内
create_agent方法将agent对象装配到regulatoryNode的属性内
该方法通过provider_title从global_state_machine中获取provider对象然后从provider对象中取出供应商形象装配为pydantic_ai的Agent实例
并挂载到self.agent属性
Args:
@@ -60,7 +60,7 @@ class SupervisoryNode:
无返回
"""
system_prompt: str = (
"你叫Pretor,是一个多智能体AI助手系统中的【监控节点 (Supervisory Node)】。\n"
"你叫kilostar,是一个多智能体AI助手系统中的【监控节点 (regulatory Node)】。\n"
"你是系统的'前台接待''大脑皮层',负责接收用户的初始请求或工作流的最终报告。\n"
"你的核心职责是进行【意图识别与路由】。请仔细阅读用户的请求:\n"
"1. 如果用户只是进行简单的问候、闲聊或查询非常基础的信息,请直接生成友好的回复,使用 ForUser 格式。\n"
@@ -70,7 +70,7 @@ class SupervisoryNode:
"请保持冷静、专业,并严格遵循上述路由规则。"
)
output_type = Union[ForConsciousnessNode, ForUser]
from pretor.utils.get_tool import load_tools_from_list
from kilostar.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
@@ -83,16 +83,16 @@ class SupervisoryNode:
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=SupervisoryNodeDeps,
agent_name="supervisory_node",
deps_type=regulatoryNodeDeps,
agent_name="regulatory_node",
tools=callables,
)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[SupervisoryNodeDeps]):
async def dynamic_prompt(ctx: RunContext[regulatoryNodeDeps]):
"""执行与 dynamic prompt 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑确保操作能够在事务上下文中被原子且一致地执行
Args: ctx (RunContext[SupervisoryNodeDeps]): 参与 dynamic prompt 逻辑运算或数据构建的上下文依赖对象
Args: ctx (RunContext[regulatoryNodeDeps]): 参与 dynamic prompt 逻辑运算或数据构建的上下文依赖对象
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
prompt = system_prompt + "\n\n"
prompt += (
@@ -117,7 +117,7 @@ class SupervisoryNode:
return prompt
###工作函数
async def working(self, payload: Union[PretorEvent, TerminationMessage]) -> str:
async def working(self, payload: Union[kilostarEvent, TerminationMessage]) -> str:
"""
working方法是节点唯一的调用方法对于_run函数的结果进行判断并实现最终回复
Args:
@@ -129,8 +129,8 @@ class SupervisoryNode:
try:
result = await self._run(payload)
if isinstance(result, ForConsciousnessNode):
self.logger.info("SupervisoryNode: 任务已分配给工作流引擎处理")
if isinstance(payload, PretorEvent):
self.logger.info("regulatoryNode: 任务已分配给工作流引擎处理")
if isinstance(payload, kilostarEvent):
try:
global_workflow_manager = ray_actor_hook(
"global_workflow_manager"
@@ -142,30 +142,30 @@ class SupervisoryNode:
await workflow_running_engine.put_event.remote(payload)
except Exception as e:
self.logger.error(
f"SupervisoryNode: 无法将事件放入 WorkflowRunningEngine: {e}"
f"regulatoryNode: 无法将事件放入 WorkflowRunningEngine: {e}"
)
return "抱歉,任务提交失败,系统内部错误。"
return f"任务已创建,准备创建工作流。原因:{result.reasoning}"
elif isinstance(result, ForUser):
self.logger.info("SupervisoryNode: 直接向用户返回简单回复。")
self.logger.info("regulatoryNode: 直接向用户返回简单回复。")
return result.context
else:
self.logger.error(f"SupervisoryNode: 未知响应类型: {type(result)}")
self.logger.error(f"regulatoryNode: 未知响应类型: {type(result)}")
return "抱歉,系统内部遇到未知错误,无法正确处理您的请求。"
except Exception:
self.logger.exception("SupervisoryNode在处理请求时发生未捕获的严重错误")
self.logger.exception("regulatoryNode在处理请求时发生未捕获的严重错误")
return "抱歉,监控节点处理请求时发生严重错误,请联系管理员。"
@overload
async def _run(self, payload: PretorEvent) -> Union[ForConsciousnessNode, ForUser]:
async def _run(self, payload: kilostarEvent) -> Union[ForConsciousnessNode, ForUser]:
"""
_run方法
Args:
payload: PretorEvent的实例是用户输入时对于消息的封装
payload: kilostarEvent的实例是用户输入时对于消息的封装
Returns:
ForUser对象监控节点对于用户进行的简单回答
ForConsciousnessNode对象监控节点将用户的请求判断为复杂任务PretorEvent传递给意识节点
ForConsciousnessNode对象监控节点将用户的请求判断为复杂任务kilostarEvent传递给意识节点
"""
...
@@ -182,7 +182,7 @@ class SupervisoryNode:
...
async def _run(
self, payload: Union[PretorEvent, TerminationMessage]
self, payload: Union[kilostarEvent, TerminationMessage]
) -> Union[ForConsciousnessNode, ForUser]:
"""
_run方法将payload转化为对llm发送的消息并发送
@@ -198,10 +198,10 @@ class SupervisoryNode:
message = payload.message
time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
deps = SupervisoryNodeDeps(
deps = regulatoryNodeDeps(
platform=platform, user_name=user_name, time=time_str
)
self.logger.debug("SupervisoryNode 开始生成 (启用原生 Pydantic-AI 重试)")
self.logger.debug("regulatoryNode 开始生成 (启用原生 Pydantic-AI 重试)")
prompt_message = message
if isinstance(payload, TerminationMessage):
prompt_message = f"【工作流执行结束报告】\n请将以下技术报告转化为对用户的友好回复:\n{message}"
@@ -209,5 +209,5 @@ class SupervisoryNode:
result = await self.agent.run(prompt_message, deps=deps)
return result.output
except Exception as e:
self.logger.exception(f"SupervisoryNode 模型生成或解析最终失败: {str(e)}")
self.logger.exception(f"regulatoryNode 模型生成或解析最终失败: {str(e)}")
return ForUser(context="系统当前负载过高或遇到复杂内部错误,请稍后再试。")
@@ -13,18 +13,18 @@
# limitations under the License.
from pydantic import Field
from pretor.utils.agent_model import ResponseModel, DepsModel
from kilostar.utils.agent_model import ResponseModel, DepsModel
from pydantic import BaseModel
class SupervisoryNodeResponse(ResponseModel):
"""SupervisoryNodeResponse 核心组件类。
class regulatoryNodeResponse(ResponseModel):
"""regulatoryNodeResponse 核心组件类。
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
pass
class ForUser(SupervisoryNodeResponse):
class ForUser(regulatoryNodeResponse):
"""ForUser 核心组件类。
这是一个领域数据模型或功能封装类承载了 ForUser 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
@@ -34,7 +34,7 @@ class ForUser(SupervisoryNodeResponse):
)
class ForConsciousnessNode(SupervisoryNodeResponse):
class ForConsciousnessNode(regulatoryNodeResponse):
"""ForConsciousnessNode 核心组件类。
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
@@ -50,8 +50,8 @@ class TerminationMessage(BaseModel):
message: str
class SupervisoryNodeDeps(DepsModel):
"""SupervisoryNodeDeps 核心组件类。
class regulatoryNodeDeps(DepsModel):
"""regulatoryNodeDeps 核心组件类。
这是一个系统执行节点类作为多智能体架构中的独立处理单元它能够接收工作流上下文根据内置的大模型策略进行意图理解和自主决策从而驱动特定阶段的任务闭环"""
platform: str
@@ -0,0 +1,3 @@
from kilostar.core.postgres_database.postgres import PostgresDatabase
__all__ = ["PostgresDatabase"]
@@ -14,9 +14,9 @@
from sqlalchemy.exc import IntegrityError, OperationalError
from pydantic import ValidationError
from pretor.utils.error import UserNotExistError
from kilostar.utils.error import UserNotExistError
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
logger = get_logger("database_exception")
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.postgres_database.table.user import User
from pretor.core.postgres_database.table.provider import Provider
from pretor.core.postgres_database.table.individual import WorkerIndividual
from kilostar.core.postgres_database.model.user import User
from kilostar.core.postgres_database.model.provider import Provider
from kilostar.core.postgres_database.model.individual import WorkerIndividual
__all__ = ["User", "Provider", "WorkerIndividual"]
@@ -11,8 +11,19 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Literal
from sqlmodel import SQLModel, Field
from .base import BaseDataModel
from sqlalchemy.orm import Mapped
class ChatHistoryMessage(BaseDataModel):
__tablename__ = "chat_history_massage"
message_id: Mapped[str]
message: Mapped[str]
message_owner: Literal["user","regulatory_node"]
class ChatHistoryRegister(BaseDataModel):
__tablename__ = "chat_history_register"
chat_id: Mapped[str]
user_id: Mapped[str]
class ChatHistory(SQLModel):
__tablename__ = "chat_history"
@@ -0,0 +1,146 @@
# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from enum import Enum
from typing import List, Optional, Dict, Any
from sqlalchemy import String, Text, text, ForeignKey
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import BaseDataModel
class ModalityType(str, Enum):
TEXT = "text"
VISION = "vision"
AUDIO = "audio"
MULTIMODAL = "multimodal"
# ==========================================
# 1. 通用基类表 (身份中心)
# ==========================================
class BaseIndividualModel(BaseDataModel):
__tablename__ = "base_individual"
agent_id: Mapped[str] = mapped_column(String(64), primary_key=True)
agent_name: Mapped[str] = mapped_column(String(100), index=True, nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
system_prompt: Mapped[Optional[str]] = mapped_column(Text)
provider_title: Mapped[str] = mapped_column(String(50))
model_id: Mapped[str] = mapped_column(String(100))
owner_id: Mapped[str] = mapped_column(String(64), index=True)
agent_type: Mapped[str] = mapped_column(String(32))
__mapper_args__ = {
"polymorphic_on": "agent_type",
"polymorphic_identity": "base"
}
# ==========================================
# 2. 专家子个体 (技能与复杂工作流)
# ==========================================
class SpecialistIndividualModel(BaseIndividualModel):
__tablename__ = "specialist_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"),
primary_key=True
)
bound_skill: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB)
workspace: Mapped[Optional[List[str]]] = mapped_column(JSONB)
tools: Mapped[Optional[List[str]]] = mapped_column(
JSONB, default=list, server_default=text("'[]'::jsonb")
)
# 逻辑关联:作为管理者,管理下属个体
sub_ordinary_agents: Mapped[List["OrdinaryIndividualModel"]] = relationship(
back_populates="manager",
cascade="all, delete-orphan",
foreign_keys="[OrdinaryIndividualModel.manager_id]"
)
sub_special_agents: Mapped[List["SpecialIndividualModel"]] = relationship(
back_populates="manager",
cascade="all, delete-orphan",
foreign_keys="[SpecialIndividualModel.manager_id]"
)
__mapper_args__ = {
"polymorphic_identity": "specialist",
}
# ==========================================
# 3. 基础子个体 (普通微调模型)
# ==========================================
class OrdinaryIndividualModel(BaseIndividualModel):
__tablename__ = "ordinary_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"),
primary_key=True
)
finetuned_from: Mapped[Optional[str]] = mapped_column(String(100))
tools: Mapped[Optional[List[str]]] = mapped_column(
JSONB, default=list, server_default=text("'[]'::jsonb")
)
# 【修复1】:必须显式定义物理外键
manager_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("specialist_individual.agent_id", ondelete="SET NULL")
)
# 逻辑关联:指向上级专家
manager: Mapped[Optional["SpecialistIndividualModel"]] = relationship(
back_populates="sub_ordinary_agents",
foreign_keys=[manager_id] # 显式指定使用 manager_id 解析关系
)
__mapper_args__ = {
"polymorphic_identity": "ordinary",
}
# ==========================================
# 4. 特殊子个体 (多模态)
# ==========================================
class SpecialIndividualModel(BaseIndividualModel):
__tablename__ = "special_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"),
primary_key=True
)
modality_type: Mapped[ModalityType] = mapped_column(
default=ModalityType.MULTIMODAL,
server_default=text("'multimodal'")
)
multimodal_config: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB)
# 【修复1】:添加缺失的物理外键
manager_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("specialist_individual.agent_id", ondelete="SET NULL")
)
# 【修复2】:修正 back_populates 指向正确的变量名
manager: Mapped[Optional["SpecialistIndividualModel"]] = relationship(
back_populates="sub_special_agents",
foreign_keys=[manager_id]
)
__mapper_args__ = {
"polymorphic_identity": "special",
}
@@ -0,0 +1,44 @@
# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List, Optional
from sqlalchemy import String, Text, Boolean, text
from sqlalchemy.dialects.postgresql import JSONB # 针对供应商模型列表优化
from sqlalchemy.orm import Mapped, mapped_column
from .base import BaseDataModel
class ProviderModel(BaseDataModel):
"""
Provider 物理模型。
作为模型/服务提供商适配器,标准化不同供应商(OpenAI, Anthropic 等)的配置。
"""
__tablename__ = "provider"
provider_id: Mapped[str] = mapped_column(String(64), primary_key=True)
provider_title: Mapped[str] = mapped_column(String(100), index=True, nullable=False)
provider_type: Mapped[str] = mapped_column(String(50), nullable=False)
provider_url: Mapped[Optional[str]] = mapped_column(Text)
provider_apikey: Mapped[Optional[str]] = mapped_column(Text)
provider_models: Mapped[List[str]] = mapped_column(
JSONB,
default=list,
server_default=text("'[]'::jsonb")
)
provider_owner: Mapped[str] = mapped_column(String(64), index=True)
is_active: Mapped[bool] = mapped_column(
Boolean,
default=True,
server_default=text("true"),
comment="该服务商节点是否在线/启用"
)
@@ -0,0 +1,35 @@
# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List, Optional
from sqlalchemy import String, Text
from sqlalchemy.dialects.postgresql import JSONB # 针对 Postgres 优化,支持索引和高性能解析
from sqlalchemy.orm import Mapped, mapped_column
from .base import BaseDataModel
class SystemNodeConfigModel(BaseDataModel):
"""
SystemNodeConfig 物理模型。
作为 kilostar 架构中的独立处理单元,负责存储 LLM 节点的执行策略与工具配置。
"""
__tablename__ = "system_node_config"
node_name: Mapped[str] = mapped_column(String(100), primary_key=True)
provider_title: Mapped[str] = mapped_column(String(50), nullable=False)
model_id: Mapped[str] = mapped_column(String(100), nullable=False)
tools: Mapped[Optional[List[str]]] = mapped_column(
JSONB,
default=list,
comment="节点可调用的工具标识列表"
)
@@ -12,14 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from sqlmodel import SQLModel, Field
from enum import IntEnum
from sqlalchemy import String, Integer, text
from sqlalchemy.orm import Mapped, mapped_column
from .base import BaseDataModel
class UserAuthority(IntEnum):
"""UserAuthority 核心组件类。
这是一个领域数据模型或功能封装类承载了 UserAuthority 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
"""
权限枚举类
"""
SUPER_ADMINISTRATOR = 100
ADMINISTRATOR = 50
USER = 20
@@ -27,12 +32,16 @@ class UserAuthority(IntEnum):
GUEST = 0
class User(SQLModel, table=True):
"""User 核心组件类。
这是一个领域数据模型或功能封装类承载了 User 相关的内聚属性定义与状态维护它的存在隔离了局部的业务复杂性并对外提供了类型安全的访问接口"""
class User(BaseDataModel):
"""
数据库user表模型
"""
__tablename__ = "user"
user_id: str = Field(primary_key=True)
user_name: str = Field(index=True)
hashed_password: str
user_authority: UserAuthority = Field(default=UserAuthority.USER)
user_id: Mapped[str] = mapped_column(String(64), primary_key=True)
user_name: Mapped[str] = mapped_column(String(100), index=True, nullable=False)
hashed_password: Mapped[str] = mapped_column(String(255), nullable=False)
user_authority: Mapped[UserAuthority] = mapped_column(
Integer,
default=UserAuthority.USER,
server_default=text("20")
)
@@ -18,6 +18,6 @@ from sqlmodel import SQLModel, Field
class EventRecord(SQLModel, table=True):
trace_id: str = Field(
primary_key=True, description="The unique trace ID of the PretorEvent"
primary_key=True, description="The unique trace ID of the kilostarEvent"
)
event_data_json: str = Field(description="The JSON serialized PretorEvent data")
event_data_json: str = Field(description="The JSON serialized kilostarEvent data")
@@ -1,6 +1,6 @@
from sqlmodel import select
from typing import List, Optional
from pretor.core.postgres_database.table.event import EventRecord
from kilostar.core.postgres_database.model.workflow import EventRecord
from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession
@@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.postgres_database.table.individual import WorkerIndividual
from kilostar.core.postgres_database.model.individual import WorkerIndividual
from sqlmodel import select
from typing import List, Optional
from pretor.core.postgres_database.database_exception import database_exception
from kilostar.core.postgres_database.database_exception import database_exception
from ulid import ULID
@@ -14,9 +14,9 @@
from typing import List
from pretor.core.postgres_database.table.provider import Provider
from kilostar.core.postgres_database.model.provider import Provider
from sqlmodel import select
from pretor.core.postgres_database.database_exception import database_exception
from kilostar.core.postgres_database.database_exception import database_exception
class ProviderDatabase:
@@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.postgres_database.table.system_node import SystemNodeConfig
from kilostar.core.postgres_database.model.system_node import SystemNodeConfig
from sqlmodel import select
from typing import List, Optional
from pretor.core.postgres_database.database_exception import database_exception
from kilostar.core.postgres_database.database_exception import database_exception
class SystemNodeDatabase:
@@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.core.postgres_database.table.user import User
from kilostar.core.postgres_database.model.user import User
from sqlmodel import select
from pretor.utils.error import UserNotExistError, UserPasswordError
from pretor.core.postgres_database.database_exception import database_exception
from pretor.core.postgres_database.table.user import UserAuthority
from pretor.utils.access import Accessor
from kilostar.utils.error import UserNotExistError, UserPasswordError
from kilostar.core.postgres_database.database_exception import database_exception
from kilostar.core.postgres_database.model.user import UserAuthority
from kilostar.utils.access import Accessor
class AuthDatabase:
View File
View File
+69
View File
@@ -0,0 +1,69 @@
# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from pydantic import BaseModel, Field
from typing import Literal, Optional
from enum import Enum
class LogicGate(BaseModel):
"""
LogicGate 类。
跳转逻辑,标记该步骤运行成功或失败的动作
"""
if_fail: str = Field(..., description="失败跳转目标,如 'jump_to_step_1'")
if_pass: Literal["continue", "exit"] = Field(default="continue", description="成功后的动作")
class WorkflowMetadata(BaseModel):
"""
WorkflowMetadata类
workflow的元数据类,保存与用户有关的数据
"""
user_id: Optional[str] = Field(default=None, description="创建工作流的用户的ulid")
command: Optional[str] = Field(default=None, description="创建工作流的原始命令")
class WorkStepStatus(str, Enum):
"""
WorkflowStepStatus 枚举类
包含workflow step运行时的状态:
PENDING: 等待工作
WORKING: 工作中
HANGUP: 挂起
COMPLETED: 完成
FAILED = 失败
"""
PENDING = "pending"
WORKING = "working"
HANGUP = "hang_up"
COMPLETED = "completed"
FAILED = "failed"
class WorkflowStatus(str, Enum):
"""
WorkflowStatus 枚举类
包含workflow运行时的状态:
RUNNING = 运行中
HANGUP = 挂起
COMPLETED = 完成
CREATING = 创建中
PENDING = 等待中
"""
RUNNING = "running"
HANGUP = "hang_up"
COMPLETED = "completed"
FAILED = "failed"
CREATING = "creating"
PENDING = "pending"
+89
View File
@@ -0,0 +1,89 @@
# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from pydantic import BaseModel, Field, model_validator
from typing import Optional, Union, List, Dict, Any
from .model import LogicGate, WorkflowMetadata, WorkStepStatus, WorkflowStatus
from ulid import ULID
from datetime import datetime
class WorkflowContext(BaseModel):
"""
WorkflowContext 类
作为workflow运行时的数据部分,使得数据和计算分离
"""
trace_id: str = Field(description="工作流的trace_id")
workflow_status: Dict[str, WorkflowStatus] = Field(default_factory=lambda: {datetime.now().strftime("%Y-%m-%d %H:%M:%S"):WorkflowStatus.CREATING} ,description="工作流状态")
blackboard: Dict[str, Any] = Field(description="大模型输出的存储区")
work_step_status: Optional[Dict[int, tuple[str, WorkStepStatus]]] = Field(default= None,description="工作流运行状态")
"""work_step_status:字典,键为整个工作流的运行步骤,值为元组,包含两个字段:
1.字符串,更新时间的字符串;2.WorkflowStatus枚举类,当前步骤的运行情况"""
workflow_pointer: Optional[int] = Field(description="工作流指针,指向具体的workflow位置")
workflow_log: List[Dict[int, tuple[str, WorkflowStatus, str]]] = Field(default=[], description="工作流运行日志")
"""workflow_log:一个列表,内部元素为一个字典,键为步骤序号,值为一个元组,包含三个字段:
1.字符串,更新时间的字符串;2.WorkflowStatus枚举类,当前步骤的运行情况;3.字符串,当前步骤运行完后的输出总结或失败原因"""
class WorkflowStep(BaseModel):
"""
WorkflowStep 类
workflow每一个步骤的模型,为workflow的最小执行单位
"""
step: int = Field(..., gt=0, description="步骤序号,严格自增")
name: str = Field(..., description="步骤名称")
action: str = Field(..., description="执行的原子动作")
inputs: Optional[Union[str, List[str]]] = Field(default=None, description="前置依赖输出")
outputs: Optional[str] = Field(default=None, description="当前步骤产出物变量名")
agent_id: Optional[str] = Field(default=None,description="分配给 skill_individual 的 Skill Individual 真实 agent_id,不可用名称代替",)
logic_gate: Optional[LogicGate] = Field(default=None, description="逻辑跳转控制")
class KiloStarWorkflow(BaseModel):
"""
KiloStarWorkflow 类
kilostar的workflow核心类,由consciousness_node创建
"""
trace_id: str = Field(default_factory=lambda: str(ULID()), description="系统自动生成的追溯ID")
version: str = Field(default="v1.0", description="系统协议版本号")
#-------------------
title: str = Field(..., description="工作流标题")
work_link: List[WorkflowStep] = Field(..., description="工作链")
workflow_metadata: WorkflowMetadata
@model_validator(mode="after")
def validate_workflow_integrity(self) -> "KiloStarWorkflow":
"""
执行与 validate workflow integrity 相关的核心业务流转操作。
该方法保证了workflow中的work_step的序号为递增且跳转逻辑不会发生越界
Returns:
('KiloStarWorkflow'): 经过校验后的KiloStarWorkflow对象。"""
steps = [s.step for s in self.work_link]
expected = list(range(1, len(steps) + 1))
if steps != expected:
raise ValueError(f"工作链步数不连续!期望 {expected},实际 {steps}")
max_step = len(steps)
for s in self.work_link:
if s.logic_gate and "jump_to_step_" in s.logic_gate.if_fail:
try:
target = int(s.logic_gate.if_fail.split("_")[-1])
if target > max_step or target < 1:
raise ValueError(
f"Step {s.step} 的跳转目标 Step {target} 越界了!"
)
except ValueError as e:
if "越界" in str(e):
raise e
raise ValueError(f"LogicGate 格式错误: {s.logic_gate.if_fail}")
return self
@@ -1,7 +1,7 @@
# workflow文档
---
- workflow(工作流)是作为pretor中运行任务的基本单位,workflow_manager管理整个workflow模块,包括生成workflow_template(工作流模板),生成workflow对象,和保存整个workflow_template表。
- workflow_template是一个工作流模板,旨在由专业人士教导LLM如何编写工作流并进行任务,每个workflow_template都应该保存在 **pretor/workflow_pugin/** 文件夹下,保存格式为~_workflow_template.jsonjson格式为:
- workflow(工作流)是作为kilostar中运行任务的基本单位,workflow_manager管理整个workflow模块,包括生成workflow_template(工作流模板),生成workflow对象,和保存整个workflow_template表。
- workflow_template是一个工作流模板,旨在由专业人士教导LLM如何编写工作流并进行任务,每个workflow_template都应该保存在 **kilostar/workflow_pugin/** 文件夹下,保存格式为~_workflow_template.jsonjson格式为:
```json
{
@@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.plugin.tool_plugin.base_tool import BaseToolData
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.plugin.tool_plugin.base_tool import BaseToolData
from kilostar.utils.ray_hook import ray_actor_hook
from typing import List, Literal, Dict
@@ -26,7 +26,7 @@ class ApprovalToolData(BaseToolData):
Literal[
"control_node",
"consciousness_node",
"supervisory_node",
"regulatory_node",
"growth_node",
"",
"",
@@ -27,7 +27,7 @@ class BaseToolData(BaseModel):
Literal[
"control_node",
"consciousness_node",
"supervisory_node",
"regulatory_node",
"growth_node",
"",
"",
@@ -13,7 +13,7 @@
# limitations under the License.
from pydantic_ai import RunContext
from pretor.plugin.tool_plugin.base_tool import BaseToolData
from kilostar.plugin.tool_plugin.base_tool import BaseToolData
import os
@@ -18,7 +18,7 @@ from datetime import datetime, timedelta, timezone
from typing import Optional
from fastapi import HTTPException, status, Request
from pydantic import BaseModel, ValidationError
from pretor.core.postgres_database.table import User
from kilostar.core.postgres_database.model import User
from pwdlib import PasswordHash
@@ -24,7 +24,7 @@ def print_banner() -> None:
with open("config/config.yml", "r") as config:
config = yaml.load(config, Loader=yaml.FullLoader)
version = config.get("version", "unknown")
pretor_banner = """
kilostar_banner = """
@@ -33,12 +33,12 @@ def print_banner() -> None:
"""
console = Console()
banner_colored = Text(pretor_banner, style="gold3 bold")
banner_colored = Text(kilostar_banner, style="gold3 bold")
console.print(banner_colored)
console.print("=" * 40, style="dim") # dim=灰色,低调
console.print("🚀 Multi-Agent Orchestration Platform", style="blue")
console.print(f"📦 Version: {version}", style="green")
console.print("👤 Author: zhaoxi826", style="yellow")
console.print("📜 License: Apache 2.0", style="magenta")
console.print("🐙 github: https://github.com/zhaoxi826/pretor", style="yellow")
console.print("🐙 github: https://github.com/zhaoxi826/kilostar", style="yellow")
console.print("=" * 40, style="dim")
@@ -13,9 +13,9 @@
# limitations under the License.
from typing import Annotated
from fastapi import Depends, HTTPException
from pretor.utils.access import Accessor, TokenData
from pretor.core.postgres_database.table import UserAuthority
from pretor.utils.ray_hook import ray_actor_hook
from kilostar.utils.access import Accessor, TokenData
from kilostar.core.postgres_database.model import UserAuthority
from kilostar.utils.ray_hook import ray_actor_hook
async def get_authority(user_id: str) -> UserAuthority:
@@ -23,7 +23,7 @@ async def get_authority(user_id: str) -> UserAuthority:
根据提供的查询条件或上下文凭证从数据库缓存或第三方服务中读取对应的资源状态
Args: user_id (str): 目标对象的唯一全局标识符 (UUID/ULID)用于在数据库表或缓存结构中精准匹配该 user 实例
Returns: (UserAuthority): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象"""
from pretor.utils.error import UserNotExistError
from kilostar.utils.error import UserNotExistError
postgres_database = ray_actor_hook("postgres_database").postgres_database
try:
@@ -17,7 +17,7 @@ import os
import sys
from typing import Callable, Dict, List
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
logger = get_logger("get_tool")
_tool_cache: Dict[str, Callable] = {}
@@ -34,7 +34,7 @@ def _get_tool_func(tool_name: str) -> Callable | None:
app_root = "/app"
tool_plugin_dir = os.path.join(
app_root, "pretor", "plugin", "tool_plugin", tool_name
app_root, "kilostar", "plugin", "tool_plugin", tool_name
)
if not os.path.exists(tool_plugin_dir) or not os.path.isdir(tool_plugin_dir):
@@ -47,7 +47,7 @@ def _get_tool_func(tool_name: str) -> Callable | None:
return None
try:
module_name = f"pretor.plugin.tool_plugin.{tool_name}"
module_name = f"kilostar.plugin.tool_plugin.{tool_name}"
spec = importlib.util.spec_from_file_location(module_name, init_file)
if spec is None or spec.loader is None:
logger.error(f"Failed to create spec for {module_name}")
@@ -50,7 +50,7 @@ class ActorList:
@lru_cache(maxsize=128)
def _get_cached_actor_handle(actor_name: str):
"""缓存接口"""
return ray.get_actor(actor_name, namespace="pretor")
return ray.get_actor(actor_name, namespace="kilostar")
def clear_actor_cache():
@@ -15,7 +15,7 @@
import asyncio
from functools import wraps
from pretor.utils.error import RetryableError
from kilostar.utils.error import RetryableError
def retry_on_retryable_error(max_retries=3, base_delay=1):
+3
View File
@@ -0,0 +1,3 @@
from kilostar.worker_cluster.worker_cluster import WorkerCluster
__all__ = ["WorkerCluster"]
@@ -17,14 +17,14 @@ import time
import asyncio
from collections import OrderedDict
from ray.util.queue import Queue
from pretor.utils.ray_hook import ray_actor_hook
from pretor.worker_individual.base_individual import BaseIndividual
from pretor.worker_individual.skill_individual import SkillIndividual
from pretor.worker_individual.ordinary_individual import OrdinaryIndividual
from pretor.worker_individual.special_individual import SpecialIndividual
from kilostar.utils.ray_hook import ray_actor_hook
from kilostar.worker_individual.base_individual import BaseIndividual
from kilostar.worker_individual.skill_individual import SkillIndividual
from kilostar.worker_individual.ordinary_individual import OrdinaryIndividual
from kilostar.worker_individual.special_individual import SpecialIndividual
from pretor.utils.logger import get_logger
from kilostar.utils.logger import get_logger
@ray.remote
@@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pretor.worker_individual.base_individual import BaseIndividual
from pretor.worker_individual.skill_individual import SkillIndividual
from pretor.worker_individual.ordinary_individual import OrdinaryIndividual
from pretor.worker_individual.special_individual import SpecialIndividual
from kilostar.worker_individual.base_individual import BaseIndividual
from kilostar.worker_individual.skill_individual import SkillIndividual
from kilostar.worker_individual.ordinary_individual import OrdinaryIndividual
from kilostar.worker_individual.special_individual import SpecialIndividual
__all__ = [
"BaseIndividual",

Some files were not shown because too many files have changed in this diff Show More