feat: 新增 task_query 工具(查询最近任务列表),为工作记忆链提供可视化入口

This commit is contained in:
root
2026-04-28 20:03:51 +08:00
parent bddb5498e9
commit 0ccd02b0af
5 changed files with 113 additions and 1 deletions

View File

@ -292,7 +292,76 @@ class EmbeddedGraphDB:
"relations": relations,
"message": f"找到 {len(entities)} 个实体, {len(relations)} 条关系"
}
def get_recent_tasks(self, limit: int = 10, state_filter: str = None) -> Dict:
"""
获取最近的任务节点
Args:
limit: 返回数量
state_filter: 可选状态过滤进行中、已完成、已暂停、已取消、archived
Returns:
{"tasks": [{"task_id": str, "description": str, "state": str,
"info_count": int, "updated_at": str}, ...]}
"""
cursor = self.conn.cursor()
# 查询所有 TaskNode 实体
cursor.execute("""
SELECT e.id, e.name, e.updated_at
FROM entities e
WHERE e.type = 'TaskNode'
ORDER BY e.updated_at DESC
LIMIT ?
""", (limit,))
rows = cursor.fetchall()
tasks = []
for row in rows:
entity_id, name, updated_at = row
# 查 description
cursor.execute("""
SELECT r.relation_type, t.name
FROM relations r
JOIN entities t ON r.target_id = t.id
WHERE r.source_id = ? AND r.status = 'active'
AND r.relation_type IN ('has_description', 'HAS_STATE')
""", (entity_id,))
desc = ""
state = "未知"
for rtype, tname in cursor.fetchall():
if rtype == 'has_description':
desc = tname
elif rtype == 'HAS_STATE':
state = tname.replace('State_', '')
# 可选状态过滤
if state_filter and state != state_filter:
continue
# 查关联信息节点数量
cursor.execute("""
SELECT COUNT(*)
FROM relations
WHERE source_id = ? AND relation_type = 'CONTAINS_INFO' AND status = 'active'
""", (entity_id,))
info_count = cursor.fetchone()[0]
tasks.append({
"task_id": name,
"description": desc,
"state": state,
"info_count": info_count,
"updated_at": updated_at
})
return {
"tasks": tasks,
"total": len(tasks)
}
def commit(self, triplets: List[Dict], entity_types: Dict = None,
temporal_tag: str = None, session_id: str = None,
turn_id: int = None) -> Dict:

View File

@ -103,6 +103,7 @@ subject, relation, object 每个字段必须是一个**短关键字**1~5个
### 任务工具(生命周期管理)
| 工具 | 时机 | 说明 |
|------|------|------|
| `task_query` | 新对话/需要回顾 | 查询最近任务列表(按更新时间倒序)。**新对话开始时优先调用此工具**,了解现有任务后再决定是继续还是创建新任务 |
| `task_create` | 新会话/新主题 | 创建任务节点。**每次新的对话会话应当创建一个独立的「当前轮对话」任务** |
| `task_set_state` | 状态变更 | 修改任务状态active、completed、archived。**旧会话结束后必须将对应的任务设为 archived** |
| `task_delete` | 确需删除的任务 | 彻底删除任务节点 |

View File

@ -105,6 +105,11 @@ def execute_tool(graph: Any, tool_name: str, arguments: dict) -> str:
result = execute_task_link_info(graph, arguments)
return json.dumps(result, ensure_ascii=False, default=str)
elif tool_name == "task_query":
recorder.record("query", tool_name, "")
result = execute_task_query(graph, arguments)
return json.dumps(result, ensure_ascii=False, default=str)
return f"未知工具: {tool_name}"
except Exception as e:
@ -352,3 +357,17 @@ def execute_task_link_info(graph: Any, arguments: dict) -> dict:
"linked_nodes": info_node_names,
"details": result
}
def execute_task_query(graph: Any, arguments: dict) -> dict:
"""查询最近的任务列表"""
limit = arguments.get("limit", 10)
state_filter = arguments.get("state_filter")
result = graph.get_recent_tasks(limit=limit, state_filter=state_filter)
return {
"status": "success",
"tasks": result["tasks"],
"total": result["total"],
"message": f"找到 {result['total']} 个任务"
}

View File

@ -45,6 +45,9 @@ class ToolLimiter:
if tool_name in ('task_create', 'task_set_state', 'task_delete', 'task_link_info'):
return ('task', 'update')
if tool_name == 'task_query':
return ('task', 'query')
if tool_name == 'memory_recall':
# 尝试区分工作记忆链查询 vs 一般记忆查询
query = (arguments.get('queryIntent', '') + ' ' + ' '.join(

View File

@ -550,6 +550,26 @@ AI操作步骤:
"required": ["task_id", "info_node_names"]
}
}
},
{
"type": "function",
"function": {
"name": "task_query",
"description": "查询最近的任务列表。按更新时间倒序排列。新对话开始时优先使用此工具获取所有进展中的任务,避免重复创建。",
"parameters": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "返回的任务数量默认10"
},
"state_filter": {
"type": "string",
"description": "按状态筛选进行中、已完成、已暂停、已取消、archived"
}
}
}
}
}
]