feat: 高德地图工具 + 多轮 bug 修复
新增: - 高德地图 6 个内置工具: amap_poi_search, amap_geocode, amap_reverse_geocode, amap_route_plan, amap_travel_plan, amap_map_link - CLI 子命令: ias tool amap (poi-search/geocode/route-plan/travel-plan/map-link) - 工具优先级指南: build_capability_guide() 含 amap > weather > web_search 优先级 - DEFAULT_SYSTEM_PROMPT 内置工具优先级说明(不再依赖环境变量) Bug 修复: 1. (HIGH) call_capability 参数契约修复 — 新增 unpack_call_params() 统一解包 prompt 字段 2. (MEDIUM) 天气 hours=0 不再调用逐时 API 3. (MEDIUM) 长期记忆 daemon 双写缓存+DB,无 DB 不丢失 4. (HIGH) 审批流程状态语义修复 — handle_reply 返回 ApprovalDecision,拒绝/过期不再当作通过 5. (HIGH) 审批有效期基于 expires_at 时间戳而非 receiver drop 6. (MEDIUM) 摘要保存改为 current_user_id 与读取一致 7. (MEDIUM) worker 审批通过后删除孤立 tool result,仅保留 approved_tool 状态放行 架构: - daemon + worker IPC 架构 (Unix Domain Socket) - build_capability_guide 共享函数消除 main.rs/worker.rs 重复
This commit is contained in:
@@ -3,6 +3,7 @@ use sha2::{Digest, Sha256};
|
||||
use sqlx::PgPool;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use tokio::sync::{Mutex, oneshot};
|
||||
|
||||
/// 审批决策
|
||||
@@ -18,6 +19,7 @@ struct PendingEntry {
|
||||
code_hash: String,
|
||||
skill_name: String,
|
||||
attempts_left: i32,
|
||||
expires_at: Instant,
|
||||
/// 通知等待方
|
||||
sender: oneshot::Sender<ApprovalDecision>,
|
||||
}
|
||||
@@ -80,6 +82,7 @@ impl ApprovalManager {
|
||||
code_hash,
|
||||
skill_name: skill_name.to_string(),
|
||||
attempts_left: 3,
|
||||
expires_at: Instant::now() + std::time::Duration::from_secs(300),
|
||||
sender: tx,
|
||||
});
|
||||
|
||||
@@ -87,8 +90,8 @@ impl ApprovalManager {
|
||||
}
|
||||
|
||||
/// 处理用户回复(由消息循环调用)
|
||||
/// 匹配成功时返回 Some(技能名),匹配失败返回 None
|
||||
pub async fn handle_reply(&self, user_id: &str, reply: &str) -> Option<String> {
|
||||
/// 返回 (技能名, 决策);匹配失败返回 None
|
||||
pub async fn handle_reply(&self, user_id: &str, reply: &str) -> Option<(String, ApprovalDecision)> {
|
||||
let (result, name, code_hash) = {
|
||||
let mut map = self.pending.lock().await;
|
||||
let entries = map.get_mut(user_id)?;
|
||||
@@ -141,17 +144,18 @@ impl ApprovalManager {
|
||||
.await;
|
||||
}
|
||||
|
||||
Some(name)
|
||||
Some((name, result))
|
||||
}
|
||||
|
||||
/// 清理过期审批(通知等待方 + 更新 DB)
|
||||
/// 清理过期审批(按时间判定,通知等待方 + 更新 DB)
|
||||
pub async fn clean_expired(&self) {
|
||||
let now = Instant::now();
|
||||
let mut expired = Vec::new();
|
||||
{
|
||||
let map = self.pending.lock().await;
|
||||
for (uid, entries) in map.iter() {
|
||||
for (i, e) in entries.iter().enumerate() {
|
||||
if e.sender.is_closed() {
|
||||
if now > e.expires_at {
|
||||
expired.push((uid.clone(), i, e.code_hash.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user