feat: 模块统一 ias- 前缀、独立版本与内网地址支持 (0.1.7)

- 所有 Rust crate 统一加 ias- 前缀:ai → ias-ai、common → ias-common、context → ias-context、mail → ias-mail、service → ias-service、wechat → ias-wechat
- 新增 ias-main 模块承载 CLI 入口和二进制打包
- 各模块开始独立维护版本号,ias-main 0.1.7 代表整体版本
- 新增 IA_WEB_INTERNAL_URL 环境变量,版本通知同时发送公网和内网链接
- 将已有升级日志翻译为中文
- ias_upgrade_logs 新增 modules JSONB 字段
- 新增 VERSION 文件和 CHANGELOG.md
- 新增 AGENTS.md 项目规则文件
This commit is contained in:
2026-07-06 17:57:48 +08:00
parent ed7f89d44f
commit 25dd0daa8b
91 changed files with 5546 additions and 777 deletions
+73
View File
@@ -0,0 +1,73 @@
use serde_json::Value;
use tokio::fs;
use crate::workflow::flow::start_flow;
use crate::workflow::types::FlowConfig;
pub async fn call_flow(path: String, args: String) -> String {
let all_flow = match load_configs(path).await {
Ok(flows) => flows,
Err(err) => return format!("工具调用失败:{:?}", err),
};
let args_json: Value = match serde_json::from_str(&args) {
Ok(json) => json,
Err(err) => return format!("工具调用失败:{:?}", err),
};
let flow_name = args_json["name"].as_str().unwrap_or_default();
if let Some(config) = all_flow.iter().find(|e| flow_name == e.name) {
let flow_result = start_flow(config, args_json["prompt"].clone()).await;
match flow_result {
Ok(value) => value,
Err(err) => format!("工具调用失败:{:?}", err),
}
} else {
"工具不存在,请检查工具名称".to_string()
}
}
pub async fn load_tools_define(path: String) -> anyhow::Result<String> {
let configs = load_configs(path).await?;
Ok(serde_json::to_string(&configs).unwrap_or_default())
}
pub async fn load_configs(path: String) -> anyhow::Result<Vec<FlowConfig>> {
let mut configs: Vec<FlowConfig> = vec![];
let config_files = scan_config_dir(path).await?;
if !config_files.is_empty() {
for file in config_files {
let config = load_yaml(file).await?;
configs.push(config);
}
}
Ok(configs)
}
pub async fn load_yaml(path: String) -> anyhow::Result<FlowConfig> {
let content: String = fs::read_to_string(path).await?;
let config = serde_yaml::from_str(&content)?;
Ok(config)
}
pub async fn scan_config_dir(path: String) -> anyhow::Result<Vec<String>> {
let mut dir = fs::read_dir(path).await?;
let mut files: Vec<String> = vec![];
while let Some(entry) = dir.next_entry().await? {
let path = entry.path();
let abs = fs::canonicalize(&path).await?;
files.push(abs.display().to_string());
}
Ok(files)
}
#[tokio::test]
async fn list_file() {
println!();
let tools = load_tools_define("../tools".to_string()).await.unwrap();
println!("{}", tools);
println!();
}