From 9b73ae4db43774b96ced3b26d62f061fc8e097bd Mon Sep 17 00:00:00 2001 From: zhaoxi Date: Sun, 14 Jun 2026 08:49:38 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=205=20=E9=A1=B9?= =?UTF-8?q?=E7=A1=AE=E5=AE=9A=20bug=20+=20Provider=20UX=20=E9=87=8D?= =?UTF-8?q?=E5=81=9A=20+=20=E6=96=87=E6=A1=A3=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug fixes: - fix(dao): AsyncSession.delete 补齐漏掉的 await(provider/user/individual 共 4 处) - fix(worker): result.data.output → result.output.output(pydantic-ai 1.x API 适配) - fix(api): 删除 create_worker_from_template 死端点(ORM 字段不匹配必崩) - fix(api): /provider/test 按 provider_type 分支适配 Anthropic/Gemini/OpenAI 三种协议 - fix(chat): SSE 流式聊天在 distributed 模式 fallback 到非流式,避免 asyncio.Queue 序列化崩溃 Features (previously unstaged): - feat(provider): Provider 管理页重做(品牌图标、5 种类型、Test Connection、编辑模式) - feat(provider): 新增 Gemini provider_type 支持 - feat(workflow): Finalize 节点输出 blackboard 摘要 + 失败原因;步骤完成/失败实时推送 SSE - feat(i18n): regulatory_node 提示词从路由模式改为直接对话模式(中英双语) - feat(consciousness): dynamic_prompt 支持 locale 国际化 - feat(logs): SystemLogsView 自动刷新 + 暂停按钮 Docs: - docs: README/README-EN 统一为"开源通用多 Agent 协作平台"口径 - docs: ROADMAP 按 v0.1.x / v0.2.x / v0.3.x 重组 - docs: project.md 重写为结构化项目介绍 Co-Authored-By: Claude Opus 4.7 (1M context) --- README-EN.md | 53 ++- README.md | 38 +- changelogs/ROADMAP.md | 80 +++- docs/project.md | 120 ++++-- .../src/components/Agent/ProviderIcon.tsx | 82 +++++ .../components/Agent/ProvidersSettings.tsx | 341 +++++++++++++++--- .../src/components/Agent/SystemLogsView.tsx | 26 +- frontend/src/i18n/locales/en.json | 26 +- frontend/src/i18n/locales/zh.json | 26 +- frontend/src/types/index.ts | 2 + kilostar/api/chat.py | 23 +- kilostar/api/provider.py | 59 ++- .../consciousness_node/consciousness_node.py | 57 ++- .../individual/consciousness_node/template.py | 3 +- .../regulatory_node/regulatory_node.py | 14 +- .../postgres_database/module/individual.py | 2 +- .../core/postgres_database/module/provider.py | 2 +- .../core/postgres_database/module/user.py | 4 +- .../core/work/workflow/workflow_engine.py | 37 +- kilostar/utils/i18n.py | 30 +- .../worker_individual/ordinary_individual.py | 2 +- .../worker_individual/skill_individual.py | 2 +- .../worker_individual/special_individual.py | 2 +- tests/unit/test_api_agent_template.py | 36 -- tests/unit/test_gsm_tool_manager.py | 2 +- tests/unit/test_individual_nodes.py | 1 + uv.lock | 2 + 27 files changed, 858 insertions(+), 214 deletions(-) create mode 100644 frontend/src/components/Agent/ProviderIcon.tsx diff --git a/README-EN.md b/README-EN.md index bd09435..556133e 100644 --- a/README-EN.md +++ b/README-EN.md @@ -2,7 +2,7 @@ # KiloStar -A distributed multi-agent collaboration system built with Python +An open-source general-purpose multi-agent collaboration platform [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/) [![Ray](https://img.shields.io/badge/Distributed-Ray-0288d1.svg)](https://docs.ray.io/) @@ -15,31 +15,58 @@ A distributed multi-agent collaboration system built with Python --- -**KiloStar** is a next-generation distributed multi-agent collaboration system powered by **Ray**. It adopts a "central oversight + edge execution" heterogeneous cluster model, leveraging large MoE models for high-level reasoning while coordinating fine-tuned lightweight models for efficient task execution. Built on **Pydantic-AI** with strong typing and a FastAPI async gateway, KiloStar delivers end-to-end automation from requirement decomposition to resource scheduling and execution. +## Overview + +**KiloStar** is an open-source general-purpose multi-agent collaboration platform that provides a complete capability stack covering model integration, agent orchestration, workflow execution, and plugin extension. The system uses **Ray** for distributed execution, **Pydantic-AI** for type-safe agent development, and exposes a unified API surface through **FastAPI**. + +The platform supports both cloud API models and locally fine-tuned models, ships with built-in core nodes for multi-agent collaboration (Regulatory, Consciousness, Control, Growth), and provides a **heavy plugin** mechanism that lets users reshape the platform into purpose-built agent applications. > **Current version**: `v0.1.1-alpha` +## Highlights + +- **Local fine-tuned models as first-class citizens**: Built-in vLLM adapter; locally fine-tuned models are interchangeable with cloud API models at the call site, allowing different agent nodes to bind different local models. +- **Heavy plugin mechanism**: Plugins can ship their own frontend pages, tool sets, and API endpoints — turning KiloStar into specialized agent applications such as coding assistants, learning helpers, or data analysis tools. +- **Multi-agent collaboration core**: Four system node types (Regulatory / Consciousness / Control / Growth) plus dynamically spawned Worker individuals, with task decomposition, scheduling, and supervision built in. +- **standalone / distributed dual mode**: Zero-dependency single-machine startup; horizontal scaling on demand. Business code is identical across both modes. +- **Private deployment friendly**: Every component runs inside the user's own environment without mandatory third-party dependencies. + --- -## ✨ Key Features +## ✨ Core Capabilities -### 🧠 Heterogeneous Agent Architecture -- **Multi-agent cluster**: Built-in Regulatory, Consciousness, Control, and Growth core nodes -- **Dynamic Worker spawning**: On-demand creation of Ordinary or Skill-type Worker Individuals +### 🧠 Multi-Agent Collaboration +- **System node specialization**: Regulatory, Consciousness, Control, and Growth nodes each cover a distinct responsibility +- **Worker dynamic spawning**: On-demand creation of Ordinary / Skill / Special Worker individuals +- **Strongly-typed communication**: Pydantic-AI constrains LLM output to structured data, eliminating the unstructured-text black box in multi-agent flows -### 🚀 Distributed Performance -- **Ray-powered**: Cross-process, cross-machine Actor communication for high-concurrency workloads -- **Local-first**: Deep vLLM integration for private model deployment +### 🚀 Distributed Execution +- **Ray Actor model**: Cross-process and cross-machine collaboration for high-concurrency workloads +- **Heterogeneous resource labels**: `kilostar_node_cpu` / `core` / `gpu` route Workers to the right physical nodes +- **Standalone mode**: Zero external dependencies for single-machine startup; shares the same business code as distributed mode ### 🔄 Workflow Engine -- **pydantic-graph based**: Directed-graph workflow orchestration with conditional branching -- **Cross-process persistence**: PostgreSQL state snapshots enabling workflow resume after interruption +- **pydantic-graph driven**: Directed-graph workflow orchestration with conditional branching and loops +- **Cross-process persistence**: PostgreSQL state snapshots enable workflow resume after interruption - **Human-in-the-Loop (HITL)**: Built-in HumanApproval node with idempotent resume semantics +### 🧩 Plugin System +- **Tool plugins**: Standard tool calls; MCP protocol support for third-party services +- **Skill (compatible with Anthropic Agent Skills spec)**: Installed and parsed via [viceroy](https://github.com/zhaoxi826/viceroy), loaded on demand at runtime +- **Heavy plugins (planned)**: Vertical application packages with dedicated UI that reshape KiloStar into specialized platforms + ### 🛡️ Security - **JWT authentication**: All API endpoints (including SSE streams) require Bearer Token auth -- **Ownership enforcement**: Workflow/chat resources are user-bound; cross-user access returns 403 -- **fetch-based SSE**: Token transmitted via Authorization header, never exposed in URLs +- **Ownership enforcement**: Workflow / chat resources are user-bound; cross-user access returns 403 +- **fetch-based SSE**: Token is transmitted via the `Authorization` header, never exposed in URLs + +### 📦 Companion Subprojects + +| Project | Codename | Purpose | Status | +|:--|:--|:--|:--| +| [kilostar-viceroy](https://github.com/zhaoxi826/viceroy) | Viceroy | Skill installation and cluster-wide distribution | ✅ Released | +| [kilostar-stardomain](./subprojects/stardomain) | Stardomain | Sandbox execution for Skill / plugin scripts | In progress | +| [kilostar-thought](https://github.com/zhaoxi826/thought) | Thought | Augmented memory system for agents | In progress | --- diff --git a/README.md b/README.md index ef6a4ed..285eba1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # KiloStar (千星) -一款基于 Python 的分布式多 Agent 协作系统 +开源通用多 Agent 协作平台 [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/) [![Ray](https://img.shields.io/badge/Distributed-Ray-0288d1.svg)](https://docs.ray.io/) @@ -15,27 +15,46 @@ --- -**KiloStar** 是一款基于 **Ray** 构建的下一代分布式多 Agent 协作系统。项目采用"中心监管 + 边缘执行"的异构集群模式,通过大参数 MoE 模型进行高层逻辑推理,并协同微调后的轻量化模型高效完成具体任务。借助 **Pydantic-AI** 提供的强类型约束与 FastAPI 异步网关,KiloStar 实现了任务从需求拆解、资源调度到自动化执行的全链路闭环。 +## 简介 + +**KiloStar** 是一个开源的通用多 Agent 协作平台,提供从模型接入、Agent 编排、工作流执行到插件扩展的完整能力栈。系统基于 **Ray** 实现分布式执行,基于 **Pydantic-AI** 提供类型安全的 Agent 开发框架,并通过 **FastAPI** 网关对外暴露统一接口。 + +平台同时支持云端 API 模型与本地微调模型,内置多 Agent 协作的核心节点(监管、意识、控制、生长),并通过**重型插件**机制允许使用者把平台改造成面向具体场景的专用 Agent 应用。 > **当前版本**:`v0.1.1-alpha` +## 项目特色 + +- **本地微调小模型一等公民**:内置 vLLM 适配,支持将本地微调模型部署为系统中的 Agent 节点,与云端 API 模型在调用层面对等 +- **重型插件机制**:插件可附带独立前端页面、工具组与 API 接口,将 KiloStar 改造为编程辅助、学习助手、数据分析等专用 Agent 应用 +- **多 Agent 协作内核**:监管 / 意识 / 控制 / 生长四类系统节点 + 动态派生的 Worker 个体,原生支持任务拆解、调度、监督的分工模式 +- **分布式与单机统一**:standalone 与 distributed 双模式共享同一套代码,单机零依赖起步,集群按需横向扩展 +- **私有化部署友好**:所有组件可在用户自有环境内运行,不强制依赖任何第三方服务 + --- -## ✨ 核心特性 +## ✨ 核心能力 -### 🧠 异构协作体系 -- **多智能体集群**:内置监控 (Regulatory)、意识 (Consciousness)、控制 (Control)、生长 (Growth) 核心节点 -- **Worker 动态派生**:根据任务需求动态拉起 Ordinary 或 Skill 类型的 Worker Individual +### 🧠 多 Agent 协作 +- **核心节点分工**:监管 (Regulatory)、意识 (Consciousness)、控制 (Control)、生长 (Growth) 四类系统节点 +- **Worker 动态派生**:根据任务需求拉起 Ordinary / Skill / Special 三种 Worker 个体 +- **强类型通信**:基于 Pydantic-AI 将 LLM 输出约束为结构化数据,避免多 Agent 协作中的非结构化文本黑盒 -### 🚀 分布式性能保障 -- **Ray 驱动**:跨进程、跨机器的 Actor 通讯,轻松应对高并发任务流 -- **本地化优先**:深度适配 vLLM,支持本地私有化模型部署 +### 🚀 分布式执行 +- **Ray Actor 模型**:跨进程、跨机器协作,支持高并发任务流 +- **异构资源标签**:`kilostar_node_cpu` / `core` / `gpu` 调度不同 Worker 到合适节点 +- **standalone 模式**:单机零依赖起步,与分布式模式共享同一套业务代码 ### 🔄 工作流引擎 - **pydantic-graph 驱动**:基于有向图的工作流编排,支持条件分支与循环 - **跨进程持久化**:PostgreSQL 状态快照,支持 workflow 中断后恢复(resume) - **人工介入 (HITL)**:内置 HumanApproval 节点,支持审批挂起与幂等恢复 +### 🧩 插件体系 +- **工具插件**:标准 Tool 调用,支持 MCP 协议接入第三方服务 +- **Skill(兼容 Anthropic Agent Skills 标准)**:通过 [viceroy](https://github.com/zhaoxi826/viceroy) 安装解析,运行时按需加载 +- **重型插件(规划中)**:带独立 UI 的垂直应用包,把 KiloStar 改造成专用 Agent 平台 + ### 🛡️ 安全设计 - **JWT 鉴权**:所有 API 端点(含 SSE 事件流)均走 Bearer Token 认证 - **归属校验**:workflow / chat 资源严格绑定 user_id,跨用户访问返回 403 @@ -46,6 +65,7 @@ | 项目 | 代号 | 功能 | 状态 | |:--|:--|:--|:--| | [kilostar-viceroy](https://github.com/zhaoxi826/viceroy) | 总督 | Skill 动态安装与全集群分发 | ✅ 已发布 | +| [kilostar-stardomain](./subprojects/stardomain) | 星域 | Skill / 插件脚本沙箱执行 | 开发中 | | [kilostar-thought](https://github.com/zhaoxi826/thought) | 思绪 | Agent 增强记忆系统 | 开发中 | --- diff --git a/changelogs/ROADMAP.md b/changelogs/ROADMAP.md index d34a194..cbf1d8d 100644 --- a/changelogs/ROADMAP.md +++ b/changelogs/ROADMAP.md @@ -1,16 +1,70 @@ +# ROADMAP + +KiloStar 各阶段的方向规划。已完成项归入 [CHANGELOG](./CHANGELOG.md)。 --- -## [v0.1.0Alpha] - 2026/4/28 -### 未来展望: -#### 功能增加 -- [ ] **完善系统插件**: 如 **RAG(检索增强生成)**,**沙箱**, **联网搜索** ,使agent拥有更多的能力适应多样化任务需求 -- [ ] **增加MCP功能**: 增加MCP,使得agent可以调用通用工具 -- [ ] **完善special_individual**: 使得`regulatory_node`等可以调用实现语言生成图像生成等功能 -- [ ] **完善regulatory_node**: 实现`regulatory_node`对于工作流状态的访问,实现更方便的检测 -- [ ] **对消息平台的对接**: 完善platform,实现对于更多消息平台的对接(如:钉钉微信等),实现在社交软件对`regulatory_node`下达命令 -#### 系统优化 -- [ ] **优化workflow逻辑**: 通过**graph**等设计实现更优秀的工作流调度 -- [ ] **优化GSM设计**: 对于 **GSM(global_state_machine全局状态机)** 进行重构,实现更高的并发 -- [ ] **工具及skill优化**: 完善前端获取工具或skill的逻辑,实现对于skill或者tool的配置改写以及详细信息获取 -- [ ] **前端优化**: 完善前端设置逻辑(如:调节语言等),以及使前端更加灵活智能 \ No newline at end of file +## v0.1.x 系列(当前) + +主线目标:补齐 v0.1.0 骨架之上的工程化与可用性短板,让平台进入"装上能用"的状态。 + +### 已完成(截至 v0.1.1-alpha) + +- **多 Agent 编排能力线**:人设模板、节点调度标签、Worker 动态派生、调控节点对话模式重构 +- **工具系统重构**:以 toolset 为单位组织工具,系统预置工具集自动补种,Agent 工具集多选绑定 +- **MCP 完整接入**:前端 CRUD、Dockerfile Node.js、后端 API 全链路落地,可作为标准 MCP 客户端调用第三方 MCP 服务器 +- **Provider UX 重做**:5 种 Provider 类型、品牌图标、默认 URL、Test Connection、API key 脱敏 +- **沙箱执行子项目**:stardomain 落地(local + Docker 双模式) +- **基础安全**:JWT 鉴权、资源归属校验、fetch-based SSE、生产密钥强制校验 + +### 计划中 + +#### 平台体验 +- **重型插件机制**:定义包格式(manifest + frontend + backend + tools + agent 配置)、挂载协议、生命周期管理;为后续生态铺路 +- **Skill 工程化**:兼容 Anthropic Agent Skills 标准的同时,补充 KiloStar 自己的 SkillManifest 抽象(依赖识别、文件分类、执行模式声明) +- **Provider 模型调用参数体系**:贯通 temperature / top_p / 自定义 headers / 超时 等模型调用参数,统一前后端 +- **前端 Tauri 桌面端**:把当前 Web 前端打包为 Tauri 桌面客户端,承载需要本地能力的功能 + +#### 模型与 Agent 能力 +- **本地微调模型集成**:vLLM 适配深化,支持把本地微调小模型部署为 Agent 节点 +- **special_individual 完善**:embedding / TTS / 图像生成等特殊 Agent 标准化接入 +- **regulatory_node 工作流可见性**:监管节点对工作流执行状态的访问与干预能力 + +#### 系统性优化 +- **GSM 写入路径优化**:单 Actor 写串行化的瓶颈处理,方向上倾向"PG 为真相之源 + GSM 退化为热缓存" +- **workflow 引擎深化**:基于 pydantic-graph 的更复杂调度模式(嵌套子流、并行分支汇聚等) +- **可观测性**:跨节点 trace 串联、workflow 执行可视化、日志检索体验 + +--- + +## v0.2.x 系列(中期) + +围绕"通用 Agent 平台"的关键缺口。 + +- **重型插件生态**:第一批官方重型插件示例 + 第三方插件开发文档 +- **Skill 分发与缓存层**:跨节点的 Skill 同步策略,按需拉取 + 本地缓存 + 哈希去重 +- **多镜像部署**:拆分 core / worker / gpu / standalone 等多镜像,按场景组合 +- **消息平台对接**:完善 platform 模块,支持钉钉 / 微信 / Slack 等平台的接入 +- **persona 外键化**:人设统一为外键引用,消除 system_prompt 的数据冗余 + +--- + +## v0.3.x 系列及之后(远期) + +- **特殊 Agent 生态**:embedding / 多模态 / 语音 / 图像生成等专项 Agent 的标准化接入 +- **生长机制**:growth_node 真正实现集群与子个体的自适应扩张 +- **微调模型工具链**:与 unsloth / axolotl 等微调框架的集成路径,把"训练 → 部署 → 接入"做成顺滑流程 +- **多用户多租户**:从单实例多用户演进到真正的多租户隔离 +- **联邦化部署**:跨组织的 Agent 协作与资源借用机制 + +--- + +## 不在路线图中 + +KiloStar 不计划自己做: + +- 任何具体垂直场景的 Agent 产品(编程助手、英语学习、数据分析等都应通过重型插件实现) +- 闭源模型的深度定制 +- 自研推理引擎(继续依托 vLLM / llama.cpp 等成熟方案) + +> 路线图按版本节奏组织,但实际推进顺序会根据使用反馈调整。重大方向变化会在此文档留痕。 diff --git a/docs/project.md b/docs/project.md index 356b3b5..c88c133 100644 --- a/docs/project.md +++ b/docs/project.md @@ -1,34 +1,102 @@ -## kilostar项目 +# KiloStar 项目介绍 -#### 简介 -**kilostar**是一款python开发,实现将小模型进行微调后整理为一个大型集群,从而实现低算力情况下高复杂度任务的实现。 -系统模型分为以下部分: -- **监管节点**:负责基本交流和简单任务执行; -- **管控节点**:负责调度系统资源; -- **意识节点**:负责复杂任务的处理; -- **生长节点**:负责扩张集群和子个体; -- **特殊子个体**:与外界交互的模型,如embedding模型,tts模型等; -- **专家子个体**:携带有专业skill的agent对象; -- **基础子个体**:普通的agent对象; ---- -#### 项目介绍 -**kilostar** 是一款基于分布式计算平台 **Ray** 和 agent开发框架**pydantic-AI** 开发的多智能体协作平台,通过多智能体的协作和任务拆解,实现复杂任务的高质量完成。 +## 简介 -**kilostar**使用 **python**著名的高性能后端框架 **Fastapi** 来作为整个系统对用户暴露接口的网关。在**kilostar**运行过程中,用户通过发送请求至fastapi从而包装为 `kilostarEvent`对象,并且发往`regulatory_node`,由**regulatory_node**进行简单的意图判断,如果判断用户只是简单交流比如聊天等,**regulatory_node**会直接对用户进行回复结束事件。 -,如果判断用户想要完成复杂的任务,**regulatory_node**会选择将从`workflow_template(工作流模板)`中选择一个或者不选择,然后将event挂到`全局状态机`实现追溯方便并发往`Workflow_Running_Engine`的异步队列,被协程对象取走后,由**consciousness_node**创建为`kilostarWorkflow`对象,挂载到实例化的`WorkflowEngine`进行执行。完成任务后返回给用户。 +**KiloStar(千星)** 是一个开源的通用多 Agent 协作平台,提供从模型接入、Agent 编排、工作流执行到插件扩展的完整能力栈。系统基于 [Ray](https://www.ray.io/) 实现分布式执行,基于 [Pydantic-AI](https://ai.pydantic.dev/) 提供类型安全的 Agent 开发框架,并通过 [FastAPI](https://fastapi.tiangolo.com/) 网关对外暴露统一接口。 + +平台同时支持云端 API 模型与本地微调模型,内置多 Agent 协作的核心系统节点,并通过**重型插件**机制允许使用者把平台改造成面向具体场景的专用 Agent 应用。 --- -#### 技术架构背景 -- 分布式大脑:利用 Ray 框架实现 Actor 模型,将不同的智能体节点(Node)部署为独立运行的分布式 Actor,具备跨节点通信和动态调度的能力。 -- 强类型通信协议:引入 PydanticAI 作为智能体开发框架,核心目的在于将大语言模型(LLM)产生的非结构化文本,通过 Pydantic 模型转化为强类型的结构化数据(JSON),确保多智能体协作时数据传输的工业级稳定性。 -- 推理驱动路由:系统针对最新的**deepseek-v4**系列进行了适配,实现灵活调用 +## 项目特色 + +1. **本地微调小模型一等公民**:内置 vLLM 适配,本地微调模型在调用层与云端 API 模型对等,使用者可以为不同 Agent 节点绑定不同的本地模型。 +2. **重型插件机制**:插件可附带独立前端页面、工具组与 API 接口,将 KiloStar 改造为编程辅助、学习助手、数据分析等专用 Agent 应用。 +3. **多 Agent 协作内核**:监管 / 意识 / 控制 / 生长四类系统节点 + 动态派生的 Worker 个体,原生支持任务拆解、调度、监督的分工模式。 +4. **standalone / distributed 双模式**:单机零依赖起步,集群按需横向扩展,业务代码在两种模式下完全一致。 +5. **私有化部署友好**:所有组件可在用户自有环境内运行,不强制依赖任何第三方服务。 --- -#### 项目背景 -###### 1.多智能体架构的需求 -随着任务复杂度的提升,单一**Agent**一定程度上以及满足不了人们对于人工智能完成复杂任务的需求。模仿人类社会中的团队合作,kilostar以**Ray**作为底座,从而实现一种多智能体协作的设计。 -###### 2.对于大语言模型输出内容约束的需求 -LLM 输出的非结构化文本在多智能体交互中极易崩溃。所以,**kilostar**没有选择如**LangChain**这种老牌智能体开发框架,而是选择了新兴的**pydanticAI**这种强约束框架,使得多智能体协作避免黑盒化。 -**PydanticAI**是一款基于**Pydantic**的智能体开发框架,**Pydantic**是**python**中著名的数据类型约束库,**Pydantic**官方通过**Pydantic**的强约束,实现了对于LLM的生成约束。 +## 系统组成 + +### 节点体系 + +| 节点类型 | 职责 | +|:--|:--| +| **Regulatory Node** | 监管节点。承担用户对话入口、意图判断、对话模式的工具调用,以及对工作流执行结果的监督 | +| **Consciousness Node** | 意识节点。负责复杂任务的拆解、规划与工作流构建 | +| **Control Node** | 控制节点。负责工作流执行过程中的路由调度与状态监控 | +| **Growth Node** | 生长节点。负责集群与子个体的扩张 | +| **Worker Individual** | Worker 个体。包括 Ordinary(基础 Agent)、Skill(携带专业技能的 Agent)、Special(与外部世界交互的特殊 Agent,例如 embedding / TTS) | + +### 模块布局 + +``` +KiloStar/ +├── kilostar/ +│ ├── api/ # FastAPI 路由层 +│ ├── core/ +│ │ ├── individual/ # 各类系统节点实现 +│ │ ├── work/ # 工作流 / 对话 / 任务执行层 +│ │ ├── global_state_machine/ # 全局状态机(Provider / Config 等) +│ │ ├── global_workflow_manager/ # 工作流消息队列 Actor +│ │ └── postgres_database/ # PostgreSQL DAO 层 +│ ├── adapter/ # 模型适配器 +│ ├── plugin/ # 工具插件 +│ ├── worker_cluster/ # Worker 集群管理 +│ ├── worker_individual/ # Worker 个体生命周期 +│ └── utils/ # 鉴权 / Ray 句柄 / 配置等 +├── frontend/ # React + Vite 前端 +├── subprojects/ # Rust 子项目(viceroy / stardomain) +├── alembic/ # 数据库迁移 +├── tests/ # 单元 + 集成测试 +└── docs/ # 设计文档 +``` + +--- + +## 技术栈 + +| 层级 | 选型 | 说明 | +|:--|:--|:--| +| 分布式运行时 | **Ray** | Actor 模型、跨进程跨机器通信、自定义资源调度 | +| Agent 框架 | **Pydantic-AI** | LLM 输出强类型约束,避免多 Agent 协作中的非结构化文本黑盒 | +| Web 网关 | **FastAPI + Ray Serve** | 异步 HTTP 网关与 SSE 事件流 | +| 工作流引擎 | **pydantic-graph** | 有向图工作流编排,支持条件分支、循环、人工介入 | +| 状态持久化 | **PostgreSQL + Alembic** | workflow 中断恢复、Agent 配置、Provider 注册等 | +| 前端 | **React 19 + Vite + Tailwind + Zustand** | TypeScript 单页应用 | +| 子项目 | **Rust** | viceroy(Skill 安装)、stardomain(沙箱执行) | + +--- + +## 运行模式 + +### standalone 单机模式 + +通过 `KILOSTAR_MODE=standalone` 启动,所有 Actor 退化为普通 Python 异步实例,无需安装 Ray,适合个人使用与开发调试。 + +### distributed 分布式模式 + +默认模式。Ray 启动后将系统节点部署为命名 Actor,WorkerCluster 按 `kilostar_node_cpu` / `core` / `gpu` 自定义资源调度到对应物理节点,支持跨机器横向扩展。 + +两种模式共享同一套业务代码,通过 `kilostar.utils.standalone_proxy` 在 Actor Handle 层做透明适配。 + +--- + +## 安全设计 + +- **JWT 鉴权**:所有 API 端点(含 SSE 事件流)均走 Bearer Token 认证 +- **资源归属校验**:workflow / chat 等用户资源严格绑定 user_id,跨用户访问返回 403 +- **fetch-based SSE**:Token 走 `Authorization` header,不暴露在 URL 中 +- **生产模式密钥校验**:未提供有效 SECRET_KEY 时拒绝以 production 模式启动 + +--- + +## 生态子项目 + +| 项目 | 代号 | 功能 | 状态 | +|:--|:--|:--|:--| +| [kilostar-viceroy](https://github.com/zhaoxi826/viceroy) | 总督 | Skill 动态安装与全集群分发 | ✅ 已发布 | +| [kilostar-stardomain](../subprojects/stardomain) | 星域 | Skill / 插件脚本沙箱执行 | 开发中 | +| [kilostar-thought](https://github.com/zhaoxi826/thought) | 思绪 | Agent 增强记忆系统 | 开发中 | diff --git a/frontend/src/components/Agent/ProviderIcon.tsx b/frontend/src/components/Agent/ProviderIcon.tsx new file mode 100644 index 0000000..00316da --- /dev/null +++ b/frontend/src/components/Agent/ProviderIcon.tsx @@ -0,0 +1,82 @@ +interface ProviderIconProps { + type: string; + size?: number; + className?: string; +} + +export function ProviderIcon({ type, size = 18, className = '' }: ProviderIconProps) { + const props = { + width: size, + height: size, + viewBox: '0 0 24 24', + fill: 'currentColor', + className, + }; + + switch (type?.toLowerCase()) { + case 'openai': + return ( + + + + ); + + case 'claude': + case 'anthropic': + return ( + + + + ); + + case 'deepseek': + return ( + + + + ); + + case 'gemini': + case 'google': + return ( + + + + ); + + case 'local': + case 'ollama': + return ( + + + + + + + + ); + + default: + return ( + + + + + ); + } +} + +const PROVIDER_BRAND_COLORS: Record = { + openai: '#10a37f', + claude: '#d97757', + anthropic: '#d97757', + deepseek: '#4d6bfe', + gemini: '#4285f4', + google: '#4285f4', + local: '#8a8a8a', + ollama: '#8a8a8a', +}; + +export function getProviderBrandColor(type: string): string { + return PROVIDER_BRAND_COLORS[type?.toLowerCase()] || '#8a8a8a'; +} diff --git a/frontend/src/components/Agent/ProvidersSettings.tsx b/frontend/src/components/Agent/ProvidersSettings.tsx index e548733..5c3dfdc 100644 --- a/frontend/src/components/Agent/ProvidersSettings.tsx +++ b/frontend/src/components/Agent/ProvidersSettings.tsx @@ -1,17 +1,51 @@ import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import { Box, Plus, X, Server, Loader2, Boxes } from 'lucide-react'; +import { Plus, X, Loader2, Boxes, Zap, ChevronDown, ChevronRight, Settings as SettingsIcon } from 'lucide-react'; import type { Provider } from '../../types'; import apiClient from '../../api/client'; +import { ProviderIcon, getProviderBrandColor } from './ProviderIcon'; + +interface ProviderTypeOption { + id: string; + iconKey: string; + backendType: 'openai' | 'claude' | 'deepseek' | 'gemini'; + defaultUrl: string; + descKey: string; + nameKey: string; +} + +const PROVIDER_TYPES: ProviderTypeOption[] = [ + { id: 'openai', iconKey: 'openai', backendType: 'openai', defaultUrl: 'https://api.openai.com/v1', nameKey: 'agent.providerTypeOpenai', descKey: 'agent.providerTypeOpenaiDesc' }, + { id: 'openai_compat', iconKey: 'openai', backendType: 'openai', defaultUrl: '', nameKey: 'agent.providerTypeOpenaiCompat', descKey: 'agent.providerTypeOpenaiCompatDesc' }, + { id: 'anthropic', iconKey: 'claude', backendType: 'claude', defaultUrl: 'https://api.anthropic.com', nameKey: 'agent.providerTypeAnthropic', descKey: 'agent.providerTypeAnthropicDesc' }, + { id: 'gemini', iconKey: 'gemini', backendType: 'gemini', defaultUrl: 'https://generativelanguage.googleapis.com/v1beta', nameKey: 'agent.providerTypeGemini', descKey: 'agent.providerTypeGeminiDesc' }, + { id: 'deepseek', iconKey: 'deepseek', backendType: 'deepseek', defaultUrl: 'https://api.deepseek.com/v1', nameKey: 'agent.providerTypeDeepseek', descKey: 'agent.providerTypeDeepseekDesc' }, +]; + +function detectTypeFromProvider(p: Provider): string { + if (p.provider_type === 'openai') { + return p.provider_url?.includes('api.openai.com') ? 'openai' : 'openai_compat'; + } + if (p.provider_type === 'claude') return 'anthropic'; + return p.provider_type || 'openai'; +} export function ProvidersSettings() { const { t } = useTranslation(); const [providers, setProviders] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); - const [formData, setFormData] = useState({ provider_type: 'openai', provider_title: '', provider_url: '', provider_apikey: '' }); + const [editingProvider, setEditingProvider] = useState(null); + const [selectedTypeId, setSelectedTypeId] = useState('openai'); + const [formData, setFormData] = useState({ provider_title: '', provider_url: '', provider_apikey: '', custom_models: '' }); + const [showAdvanced, setShowAdvanced] = useState(false); const [submitLoading, setSubmitLoading] = useState(false); + const [testLoading, setTestLoading] = useState(false); + const [testResult, setTestResult] = useState<{ success: boolean; error?: string; model_count?: number } | null>(null); const [error, setError] = useState(''); + const [expandedProvider, setExpandedProvider] = useState(null); + + const selectedType = PROVIDER_TYPES.find((p) => p.id === selectedTypeId) || PROVIDER_TYPES[0]; const fetchProviders = async () => { setLoading(true); @@ -19,7 +53,7 @@ export function ProvidersSettings() { const response = await apiClient.get('/api/v1/provider/list'); setProviders(Object.values(response.data.provider_list || {})); } catch (error) { - console.error("Failed to fetch providers", error); + console.error('Failed to fetch providers', error); setProviders([]); } finally { setLoading(false); @@ -28,6 +62,72 @@ export function ProvidersSettings() { useEffect(() => { fetchProviders(); }, []); + const openAddModal = () => { + setEditingProvider(null); + setSelectedTypeId('openai'); + setFormData({ provider_title: '', provider_url: PROVIDER_TYPES[0].defaultUrl, provider_apikey: '', custom_models: '' }); + setError(''); + setTestResult(null); + setShowAdvanced(false); + setIsModalOpen(true); + }; + + const openEditModal = (provider: Provider) => { + const typeId = detectTypeFromProvider(provider); + setEditingProvider(provider.provider_title); + setSelectedTypeId(typeId); + setFormData({ + provider_title: provider.provider_title, + provider_url: provider.provider_url || '', + provider_apikey: '', + custom_models: '', + }); + setError(''); + setTestResult(null); + setShowAdvanced(false); + setIsModalOpen(true); + }; + + const handleSelectType = (typeId: string) => { + setSelectedTypeId(typeId); + if (!editingProvider) { + const tp = PROVIDER_TYPES.find((p) => p.id === typeId); + if (tp) setFormData((prev) => ({ ...prev, provider_url: tp.defaultUrl })); + } + setTestResult(null); + }; + + const buildPayload = () => { + const customModels = formData.custom_models + .split(',').map((s) => s.trim()).filter(Boolean); + const payload: any = { + provider_type: selectedType.backendType, + provider_title: formData.provider_title, + provider_url: formData.provider_url, + provider_apikey: formData.provider_apikey, + }; + if (customModels.length > 0) payload.custom_models = customModels; + return payload; + }; + + const handleTestConnection = async () => { + if (!formData.provider_url || !formData.provider_apikey) { + setError(t('agent.providerFillUrlAndKey')); + return; + } + setTestLoading(true); + setTestResult(null); + setError(''); + try { + const resp = await apiClient.post('/api/v1/provider/test', buildPayload()); + setTestResult(resp.data); + } catch { + setTestResult({ success: false, error: 'Request failed' }); + } finally { + setTestLoading(false); + } + }; + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.provider_title || !formData.provider_url || !formData.provider_apikey) { @@ -37,9 +137,13 @@ export function ProvidersSettings() { setSubmitLoading(true); setError(''); try { - await apiClient.post('/api/v1/provider', formData); + if (editingProvider) { + await apiClient.delete(`/api/v1/provider/${editingProvider}`); + } + await apiClient.post('/api/v1/provider', buildPayload()); await fetchProviders(); setIsModalOpen(false); + setEditingProvider(null); } catch (err) { setError(t('agent.providerAddFailed')); } finally { @@ -54,7 +158,7 @@ export function ProvidersSettings() {

{t('agent.providerManagement')}

{t('agent.providerDesc')}

- @@ -76,25 +180,43 @@ export function ProvidersSettings() {
-
- +
+

{provider.provider_title}

{provider.provider_type}
- - {provider.status === 'Connected' && } - {provider.status || t('common.unknown')} + + {(provider.status === 'Connected' || provider.provider_status === 'up') && } + {provider.provider_status === 'up' ? 'Connected' : provider.status || t('common.unknown')}
-
+

{t('agent.endpoint')}

{provider.provider_url || t('common.default')}

+ {provider.provider_models && provider.provider_models.length > 0 && ( +
+ + {expandedProvider === provider.provider_title && ( +
+ {provider.provider_models.map((model: string) => ( +
{model}
+ ))} +
+ )} +
+ )}
- +
)} - {/* Modal */} + {/* Modal — 2 column layout */} {isModalOpen && ( -
-
-
-
- -

{t('agent.addNewProvider')}

-
- +
+
+
+

+ {editingProvider ? t('agent.editProvider') : t('agent.addNewProvider')} +

+
-
- {error &&
{error}
} -
- - -
- {['provider_title', 'provider_url', 'provider_apikey'].map((field) => ( -
- - setFormData({...formData, [field]: e.target.value})} - placeholder={field === 'provider_title' ? t('agent.providerTitlePlaceholder') : field === 'provider_url' ? t('agent.baseUrlPlaceholder') : t('agent.apiKeyPlaceholder')} - className="w-full bg-bg-input border border-border-primary text-sm rounded-xl px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent text-text-primary placeholder:text-text-muted/50 font-mono" /> + + + {/* Left: provider type list */} +
+
+ {t('agent.providerType')} +
+ {PROVIDER_TYPES.map((type) => { + const active = selectedTypeId === type.id; + return ( + + ); + })} +
+ + {/* Right: form */} +
+ {error &&
{error}
} + {testResult && ( +
+ {testResult.success + ? `${t('agent.providerTestSuccess')} · ${testResult.model_count} ${t('agent.providerModels')}` + : `${t('agent.providerTestFailed')}: ${testResult.error}`} +
+ )} + +
+ + setFormData({ ...formData, provider_title: e.target.value })} + placeholder={t('agent.providerTitlePlaceholder')} + disabled={!!editingProvider} + className="w-full bg-bg-input border border-border-primary text-sm rounded-xl px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent text-text-primary placeholder:text-text-muted/50 disabled:opacity-50" + /> +
+ +
+ + setFormData({ ...formData, provider_url: e.target.value })} + placeholder={selectedType.defaultUrl || t('agent.baseUrlPlaceholder')} + className="w-full bg-bg-input border border-border-primary text-sm rounded-xl px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent text-text-primary placeholder:text-text-muted/50 font-mono" + /> + {selectedType.defaultUrl && !editingProvider && ( +

+ {t('agent.baseUrlHint')}: {selectedType.defaultUrl} +

+ )} +
+ +
+ + setFormData({ ...formData, provider_apikey: e.target.value })} + placeholder={editingProvider ? t('agent.apiKeyEditPlaceholder') : t('agent.apiKeyPlaceholder')} + className="w-full bg-bg-input border border-border-primary text-sm rounded-xl px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent text-text-primary placeholder:text-text-muted/50 font-mono" + /> +
+ + {/* 参数设置 — collapsible */} +
+ + {showAdvanced && ( +
+
+ +