refactor: 大规模模块拆分与代码精简,新增 ai-pipeline/data-contracts 独立 crate

- 新增 aether-ai-pipeline 和 aether-data-contracts crate,将 pipeline 逻辑与数据契约从 gateway 中解耦
- 重构 admin handlers:拆分单体模块为 auth/billing/endpoint/features/model/observability/provider/system 等独立子模块
- 合并 chat/cli 重复代码路径:精简 conversion、finalize、planner 中的 sync/chat/cli 分支
- 重构 scheduler/executor/data 层,引入 facade 模式降低模块间耦合
- 移除冗余的 intent 模块,将 plan_fallback/policy/stream_path/sync_path 迁移至 executor
- 前端适配:调整 admin API 调用和 provider 模型测试对话框
This commit is contained in:
fawney19
2026-04-07 02:50:19 +08:00
parent 763ff03a7b
commit 5d96d6673b
732 changed files with 28593 additions and 20666 deletions

View File

@@ -1,3 +1,4 @@
use crate::error::RedisResultExt;
use crate::redis::RedisKeyspace;
use crate::DataLayerError;
@@ -44,7 +45,7 @@ impl RedisClientFactory {
}
pub fn connect_lazy(&self) -> Result<RedisClient, DataLayerError> {
Ok(RedisClient::open(self.config.url.clone())?)
RedisClient::open(self.config.url.clone()).map_redis_err()
}
}

View File

@@ -1,6 +1,7 @@
use std::future::Future;
use std::time::Duration;
use crate::error::RedisResultExt;
use crate::redis::{RedisClient, RedisKeyspace};
use crate::DataLayerError;
@@ -79,13 +80,18 @@ impl RedisKvRunner {
let resolved_ttl = ttl_seconds.unwrap_or(self.config.default_ttl_seconds);
let namespaced_key = self.keyspace.key(key);
self.run_with_timeout("redis kv setex", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
Ok(redis::cmd("SETEX")
.arg(&namespaced_key)
.arg(resolved_ttl)
.arg(value)
.query_async(&mut connection)
.await?)
.await
.map_redis_err()?)
})
.await
}
@@ -93,11 +99,16 @@ impl RedisKvRunner {
pub async fn del(&self, key: &str) -> Result<i64, DataLayerError> {
let namespaced_key = self.keyspace.key(key);
self.run_with_timeout("redis kv del", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
Ok(redis::cmd("DEL")
.arg(&namespaced_key)
.query_async(&mut connection)
.await?)
.await
.map_redis_err()?)
})
.await
}

View File

@@ -1,6 +1,7 @@
use std::future::Future;
use std::time::Duration;
use crate::error::RedisResultExt;
use crate::redis::{RedisClient, RedisKeyspace};
use crate::DataLayerError;
use uuid::Uuid;
@@ -92,7 +93,11 @@ impl RedisLockRunner {
let token = format!("{owner}:{}", Uuid::new_v4());
self.run_with_timeout("redis lock acquire", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let status = redis::cmd("SET")
.arg(&key.0)
.arg(&token)
@@ -100,7 +105,8 @@ impl RedisLockRunner {
.arg("PX")
.arg(ttl_ms)
.query_async::<Option<String>>(&mut connection)
.await?;
.await
.map_redis_err()?;
Ok(status.map(|_| RedisLockLease {
key: key.clone(),
@@ -115,7 +121,11 @@ impl RedisLockRunner {
pub async fn release(&self, lease: &RedisLockLease) -> Result<bool, DataLayerError> {
validate_lease(lease)?;
self.run_with_timeout("redis lock release", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let deleted = redis::Script::new(
"if redis.call('get', KEYS[1]) == ARGV[1] then \
return redis.call('del', KEYS[1]) \
@@ -126,7 +136,8 @@ impl RedisLockRunner {
.key(&lease.key.0)
.arg(&lease.token)
.invoke_async::<i32>(&mut connection)
.await?;
.await
.map_redis_err()?;
Ok(deleted > 0)
})
.await
@@ -141,7 +152,11 @@ impl RedisLockRunner {
let ttl_ms = self.resolve_ttl_ms(ttl_ms)?;
self.run_with_timeout("redis lock renew", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let renewed = redis::Script::new(
"if redis.call('get', KEYS[1]) == ARGV[1] then \
return redis.call('pexpire', KEYS[1], ARGV[2]) \
@@ -153,7 +168,8 @@ impl RedisLockRunner {
.arg(&lease.token)
.arg(ttl_ms)
.invoke_async::<i32>(&mut connection)
.await?;
.await
.map_redis_err()?;
Ok(renewed > 0)
})
.await

View File

@@ -6,6 +6,7 @@ use redis::from_redis_value;
use redis::streams::StreamReadReply;
use redis::Value as RedisValue;
use crate::error::{redis_error, RedisResultExt};
use crate::redis::{RedisClient, RedisKeyspace};
use crate::DataLayerError;
@@ -154,7 +155,11 @@ impl RedisStreamRunner {
validate_stream_position(start_id)?;
self.run_with_timeout("redis stream ensure consumer group", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let result = redis::cmd("XGROUP")
.arg("CREATE")
.arg(&stream.0)
@@ -167,7 +172,7 @@ impl RedisStreamRunner {
match result {
Ok(_) => Ok(()),
Err(err) if err.code() == Some("BUSYGROUP") => Ok(()),
Err(err) => Err(DataLayerError::Redis(err)),
Err(err) => Err(redis_error(err)),
}
})
.await
@@ -195,7 +200,11 @@ impl RedisStreamRunner {
}
self.run_with_timeout("redis stream append", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let mut command = redis::cmd("XADD");
command.arg(&stream.0);
if let Some(maxlen) = maxlen.filter(|value| *value > 0) {
@@ -205,7 +214,10 @@ impl RedisStreamRunner {
for (key, value) in fields {
command.arg(key).arg(value);
}
Ok(command.query_async::<String>(&mut connection).await?)
Ok(command
.query_async::<String>(&mut connection)
.await
.map_redis_err()?)
})
.await
}
@@ -245,7 +257,11 @@ impl RedisStreamRunner {
validate_consumer(consumer)?;
self.run_with_timeout("redis stream read group", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let mut command = redis::cmd("XREADGROUP");
command
.arg("GROUP")
@@ -260,7 +276,8 @@ impl RedisStreamRunner {
let reply = command
.query_async::<StreamReadReply>(&mut connection)
.await?;
.await
.map_redis_err()?;
Ok(reply
.keys
@@ -296,13 +313,20 @@ impl RedisStreamRunner {
}
self.run_with_timeout("redis stream ack", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let mut command = redis::cmd("XACK");
command.arg(&stream.0).arg(&group.0);
for id in ids {
command.arg(id);
}
Ok(command.query_async::<usize>(&mut connection).await?)
Ok(command
.query_async::<usize>(&mut connection)
.await
.map_redis_err()?)
})
.await
}
@@ -318,13 +342,20 @@ impl RedisStreamRunner {
}
self.run_with_timeout("redis stream delete", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let mut command = redis::cmd("XDEL");
command.arg(&stream.0);
for id in ids {
command.arg(id);
}
Ok(command.query_async::<usize>(&mut connection).await?)
Ok(command
.query_async::<usize>(&mut connection)
.await
.map_redis_err()?)
})
.await
}
@@ -344,7 +375,11 @@ impl RedisStreamRunner {
config.validate()?;
self.run_with_timeout("redis stream reclaim", async {
let mut connection = self.client.get_multiplexed_async_connection().await?;
let mut connection = self
.client
.get_multiplexed_async_connection()
.await
.map_redis_err()?;
let reply = redis::cmd("XAUTOCLAIM")
.arg(&stream.0)
.arg(&group.0)
@@ -354,7 +389,8 @@ impl RedisStreamRunner {
.arg("COUNT")
.arg(config.count)
.query_async::<RedisValue>(&mut connection)
.await?;
.await
.map_redis_err()?;
parse_reclaim_result(reply)
})