新增: 初始化 DevFlow 项目仓库
Tauri 2 + Vue 3 + Vite 6 桌面应用,Rust workspace 含 13 个 crate (df-ai / df-storage / df-workflow / df-core / df-execute 等)。 核心能力:AI 聊天 agentic 循环(工具调用+人工审批)、工作流引擎、 任务/想法/项目/阶段管理、可追溯性,及配套前端组件。
This commit is contained in:
14
crates/df-plugin/Cargo.toml
Normal file
14
crates/df-plugin/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "df-plugin"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
df-core = { path = "../df-core" }
|
||||
df-workflow = { path = "../df-workflow" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
66
crates/df-plugin/src/host.rs
Normal file
66
crates/df-plugin/src/host.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
//! 插件宿主环境 — 管理插件生命周期与沙箱
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use df_core::types::PluginId;
|
||||
use df_workflow::node::Node;
|
||||
|
||||
use crate::loader::{LoadedPlugin, PluginLoader, PluginMetadata};
|
||||
|
||||
/// 插件宿主环境
|
||||
pub struct PluginHost {
|
||||
/// 插件加载器
|
||||
loader: PluginLoader,
|
||||
/// 已加载的插件
|
||||
plugins: HashMap<PluginId, LoadedPlugin>,
|
||||
}
|
||||
|
||||
impl PluginHost {
|
||||
/// 创建宿主环境
|
||||
pub fn new(loader: PluginLoader) -> Self {
|
||||
Self {
|
||||
loader,
|
||||
plugins: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化:加载所有插件
|
||||
pub async fn initialize(&mut self) -> anyhow::Result<()> {
|
||||
self.plugins = self.loader.load_all()?;
|
||||
tracing::info!("插件宿主环境初始化完成,加载了 {} 个插件", self.plugins.len());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 获取所有已注册的节点
|
||||
pub fn all_nodes(&self) -> Vec<(&PluginId, &Box<dyn Node>)> {
|
||||
let mut nodes = Vec::new();
|
||||
for (plugin_id, plugin) in &self.plugins {
|
||||
for node in &plugin.nodes {
|
||||
nodes.push((plugin_id, node));
|
||||
}
|
||||
}
|
||||
nodes
|
||||
}
|
||||
|
||||
/// 获取指定插件的元数据
|
||||
pub fn get_metadata(&self, plugin_id: &PluginId) -> Option<&PluginMetadata> {
|
||||
self.plugins.get(plugin_id).map(|p| &p.metadata)
|
||||
}
|
||||
|
||||
/// 卸载指定插件
|
||||
///
|
||||
/// TODO: 实现插件卸载(清理资源、取消注册节点等)
|
||||
pub fn unload(&mut self, plugin_id: &PluginId) -> anyhow::Result<()> {
|
||||
if let Some(plugin) = self.plugins.remove(plugin_id) {
|
||||
tracing::info!("插件 {} 已卸载", plugin.metadata.name);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 关闭宿主环境,卸载所有插件
|
||||
pub fn shutdown(&mut self) {
|
||||
let count = self.plugins.len();
|
||||
self.plugins.clear();
|
||||
tracing::info!("插件宿主环境关闭,卸载了 {} 个插件", count);
|
||||
}
|
||||
}
|
||||
5
crates/df-plugin/src/lib.rs
Normal file
5
crates/df-plugin/src/lib.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
//! df-plugin: 插件系统 — 插件加载、宿主环境、SDK
|
||||
|
||||
pub mod host;
|
||||
pub mod loader;
|
||||
pub mod sdk;
|
||||
94
crates/df-plugin/src/loader.rs
Normal file
94
crates/df-plugin/src/loader.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
//! 插件加载器 — 发现、加载、注册插件
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use df_core::types::PluginId;
|
||||
use df_workflow::node::Node;
|
||||
|
||||
/// 插件元数据
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PluginMetadata {
|
||||
/// 插件 ID
|
||||
pub id: PluginId,
|
||||
/// 插件名称
|
||||
pub name: String,
|
||||
/// 版本
|
||||
pub version: String,
|
||||
/// 描述
|
||||
pub description: String,
|
||||
/// 作者
|
||||
pub author: Option<String>,
|
||||
/// 入口文件路径
|
||||
pub entry_path: PathBuf,
|
||||
}
|
||||
|
||||
/// 已加载的插件
|
||||
pub struct LoadedPlugin {
|
||||
pub metadata: PluginMetadata,
|
||||
pub nodes: Vec<Box<dyn Node>>,
|
||||
}
|
||||
|
||||
/// 插件加载器
|
||||
pub struct PluginLoader {
|
||||
/// 插件搜索目录
|
||||
search_dirs: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl PluginLoader {
|
||||
/// 创建插件加载器
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
search_dirs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 添加插件搜索目录
|
||||
pub fn add_search_dir(&mut self, dir: PathBuf) {
|
||||
self.search_dirs.push(dir);
|
||||
}
|
||||
|
||||
/// 扫描并发现所有可用插件
|
||||
///
|
||||
/// TODO: 实现文件系统扫描、manifest 解析
|
||||
pub fn discover(&self) -> anyhow::Result<Vec<PluginMetadata>> {
|
||||
tracing::info!("扫描插件目录: {:?}", self.search_dirs);
|
||||
// TODO: 实现插件发现逻辑
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
/// 加载指定插件
|
||||
///
|
||||
/// TODO: 实现动态库加载(dlopen/LoadLibrary)或 WASM 加载
|
||||
pub fn load(&self, _metadata: &PluginMetadata) -> anyhow::Result<LoadedPlugin> {
|
||||
// TODO: 实现插件加载
|
||||
tracing::warn!("插件加载尚未实现");
|
||||
Err(anyhow::anyhow!("插件加载尚未实现"))
|
||||
}
|
||||
|
||||
/// 批量加载所有发现的插件
|
||||
pub fn load_all(&self) -> anyhow::Result<HashMap<PluginId, LoadedPlugin>> {
|
||||
let metadata_list = self.discover()?;
|
||||
let mut loaded = HashMap::new();
|
||||
|
||||
for meta in metadata_list {
|
||||
match self.load(&meta) {
|
||||
Ok(plugin) => {
|
||||
tracing::info!("插件 {} v{} 加载成功", meta.name, meta.version);
|
||||
loaded.insert(meta.id.clone(), plugin);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("插件 {} 加载失败: {}", meta.name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(loaded)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PluginLoader {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
90
crates/df-plugin/src/sdk.rs
Normal file
90
crates/df-plugin/src/sdk.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
//! 插件 SDK — 插件开发者使用的工具与trait
|
||||
|
||||
use async_trait::async_trait;
|
||||
use df_workflow::node::Node;
|
||||
|
||||
/// 插件入口 trait — 所有插件必须实现
|
||||
#[async_trait]
|
||||
pub trait Plugin: Send + Sync {
|
||||
/// 插件 ID
|
||||
fn id(&self) -> &str;
|
||||
|
||||
/// 插件名称
|
||||
fn name(&self) -> &str;
|
||||
|
||||
/// 插件版本
|
||||
fn version(&self) -> &str;
|
||||
|
||||
/// 注册的所有节点
|
||||
fn nodes(&self) -> Vec<Box<dyn Node>>;
|
||||
|
||||
/// 插件初始化(可选)
|
||||
async fn initialize(&self) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 插件销毁(可选)
|
||||
async fn shutdown(&self) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// 插件构建器 — 简化插件定义
|
||||
pub struct PluginBuilder {
|
||||
id: String,
|
||||
name: String,
|
||||
version: String,
|
||||
nodes: Vec<Box<dyn Node>>,
|
||||
}
|
||||
|
||||
impl PluginBuilder {
|
||||
/// 创建插件构建器
|
||||
pub fn new(id: impl Into<String>, name: impl Into<String>, version: impl Into<String>) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
name: name.into(),
|
||||
version: version.into(),
|
||||
nodes: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 注册节点
|
||||
pub fn node(mut self, node: Box<dyn Node>) -> Self {
|
||||
self.nodes.push(node);
|
||||
self
|
||||
}
|
||||
|
||||
/// 获取插件 ID
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// 获取插件名称
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// 获取插件版本
|
||||
pub fn version(&self) -> &str {
|
||||
&self.version
|
||||
}
|
||||
|
||||
/// 构建并获取所有节点
|
||||
pub fn build(self) -> Vec<Box<dyn Node>> {
|
||||
self.nodes
|
||||
}
|
||||
}
|
||||
|
||||
/// 声明插件的宏(简化版)
|
||||
///
|
||||
/// TODO: 实现完整的声明宏
|
||||
/// 使用示例:
|
||||
/// ```
|
||||
/// declare_plugin!("my-plugin", "My Plugin", "0.1.0");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! declare_plugin {
|
||||
($id:expr, $name:expr, $version:expr) => {
|
||||
// TODO: 实现宏
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user