Update nexus: fix conflicts and sync local changes

This commit is contained in:
Shen Wei
2026-04-26 12:06:50 +08:00
parent 191797c01b
commit f09834b5a5
2443 changed files with 254323 additions and 255154 deletions

View File

@@ -1,215 +1,215 @@
#!/usr/bin/env python3
"""
Agent 任务轮询脚本
每个 Agent 定时运行,查询分配给自己的任务并执行
"""
import os
import sys
import time
import logging
import requests
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# 环境变量或配置
NOTION_TOKEN = os.environ.get("NOTION_TOKEN", "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")
AGENT_ID = os.environ.get("AGENT_ID", "yunjiang") # 当前 Agent ID
POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", "180")) # 轮询间隔默认3分钟
# Database IDs
TASKS_DB_ID = "32847fe1-da27-8135-af44-eefdbd3b1640"
AGENTS_DB_ID = "32847fe1-da27-8101-8758-d416db87d4de"
# Notion API 基础 URL
NOTION_API_BASE = "https://api.notion.com/v1"
def notion_request(method, endpoint, **kwargs):
"""Notion API 请求封装"""
url = f"{NOTION_API_BASE}{endpoint}"
headers = {
"Authorization": f"Bearer {NOTION_TOKEN}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
if method == "GET":
response = requests.get(url, headers=headers, **kwargs)
elif method == "POST":
response = requests.post(url, headers=headers, **kwargs)
elif method == "PATCH":
response = requests.patch(url, headers=headers, **kwargs)
else:
raise ValueError(f"Unsupported method: {method}")
response.raise_for_status()
return response.json()
def get_agent_info(agent_id):
"""获取 Agent 信息"""
response = notion_request("POST", f"/databases/{AGENTS_DB_ID}/query")
for page in response.get("results", []):
props = page.get("properties", {})
if "Agent ID" in props:
title = props["Agent ID"]["title"]
if title and title[0]["plain_text"] == agent_id:
return {
"id": page["id"],
"name": props["名称"]["rich_text"][0]["plain_text"] if props["名称"]["rich_text"] else agent_id,
"status": props["状态"]["select"]["name"] if props["状态"].get("select") else "离线"
}
return None
def query_todo_tasks(agent_page_id=None):
"""查询 TODO 任务"""
logger.info(f"查询 {AGENT_ID} 的 TODO 任务...")
# 如果有 agent_page_id使用 Relation 过滤
filter_dict = {
"property": "状态",
"select": {
"equals": "TODO"
}
}
# 这里简化处理:查询所有 TODO 任务
# 后续应该根据执行者 Relation 过滤
try:
response = notion_request(
"POST",
f"/databases/{TASKS_DB_ID}/query",
json={"filter": filter_dict}
)
tasks = response.get("results", [])
logger.info(f"找到 {len(tasks)} 个 TODO 任务")
return tasks
except Exception as e:
logger.error(f"查询任务失败: {e}")
return []
def claim_task(task_id):
"""领取任务:将状态改为进行中"""
try:
notion_request(
"PATCH",
f"/pages/{task_id}",
json={
"properties": {
"状态": {
"select": {"name": "进行中"}
}
}
}
)
logger.info(f"✓ 领取任务成功: {task_id}")
return True
except Exception as e:
logger.error(f"领取任务失败: {e}")
return False
def complete_task(task_id, report_link):
"""完成任务:将状态改为待验收"""
try:
notion_request(
"PATCH",
f"/pages/{task_id}",
json={
"properties": {
"状态": {
"select": {"name": "待验收"}
},
"报告链接": {
"url": report_link
}
}
}
)
logger.info(f"✓ 完成任务: {task_id}")
return True
except Exception as e:
logger.error(f"完成任务失败: {e}")
return False
def execute_task(task):
"""执行任务的逻辑(可自定义)"""
# 获取任务信息
props = task.get("properties", {})
task_name = props.get("任务名", {}).get("title", [{}])[0].get("plain_text", "未命名任务")
task_id = task["id"]
logger.info(f"开始执行任务: {task_name}")
# 1. 领取任务
if not claim_task(task_id):
return False
# 2. 执行任务(这里只是示例,实际应根据任务类型执行不同操作)
# 模拟执行
time.sleep(2)
# 3. 完成任务(生成报告链接)
# 这里应该生成实际的 Obsidian 报告
report_link = f"https://example.com/report/{task_id}"
return complete_task(task_id, report_link)
def polling_loop():
"""轮询主循环"""
logger.info(f"🚀 Agent {AGENT_ID} 任务轮询启动")
logger.info(f"轮询间隔: {POLL_INTERVAL}")
# 获取 Agent 信息
agent_info = get_agent_info(AGENT_ID)
if agent_info:
logger.info(f"Agent 信息: {agent_info['name']} (状态: {agent_info['status']})")
else:
logger.warning(f"未找到 Agent: {AGENT_ID}")
while True:
try:
# 查询 TODO 任务
tasks = query_todo_tasks(None)
if tasks:
logger.info(f"发现 {len(tasks)} 个待处理任务")
for task in tasks:
execute_task(task)
else:
logger.debug("没有待处理任务")
except Exception as e:
logger.error(f"轮询异常: {e}")
time.sleep(POLL_INTERVAL)
def main():
"""主入口"""
if len(sys.argv) > 1:
global AGENT_ID
AGENT_ID = sys.argv[1]
if len(sys.argv) > 2:
global POLL_INTERVAL
POLL_INTERVAL = int(sys.argv[2])
polling_loop()
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Agent 任务轮询脚本
每个 Agent 定时运行,查询分配给自己的任务并执行
"""
import os
import sys
import time
import logging
import requests
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# 环境变量或配置
NOTION_TOKEN = os.environ.get("NOTION_TOKEN", "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")
AGENT_ID = os.environ.get("AGENT_ID", "yunjiang") # 当前 Agent ID
POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", "180")) # 轮询间隔默认3分钟
# Database IDs
TASKS_DB_ID = "32847fe1-da27-8135-af44-eefdbd3b1640"
AGENTS_DB_ID = "32847fe1-da27-8101-8758-d416db87d4de"
# Notion API 基础 URL
NOTION_API_BASE = "https://api.notion.com/v1"
def notion_request(method, endpoint, **kwargs):
"""Notion API 请求封装"""
url = f"{NOTION_API_BASE}{endpoint}"
headers = {
"Authorization": f"Bearer {NOTION_TOKEN}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
if method == "GET":
response = requests.get(url, headers=headers, **kwargs)
elif method == "POST":
response = requests.post(url, headers=headers, **kwargs)
elif method == "PATCH":
response = requests.patch(url, headers=headers, **kwargs)
else:
raise ValueError(f"Unsupported method: {method}")
response.raise_for_status()
return response.json()
def get_agent_info(agent_id):
"""获取 Agent 信息"""
response = notion_request("POST", f"/databases/{AGENTS_DB_ID}/query")
for page in response.get("results", []):
props = page.get("properties", {})
if "Agent ID" in props:
title = props["Agent ID"]["title"]
if title and title[0]["plain_text"] == agent_id:
return {
"id": page["id"],
"name": props["名称"]["rich_text"][0]["plain_text"] if props["名称"]["rich_text"] else agent_id,
"status": props["状态"]["select"]["name"] if props["状态"].get("select") else "离线"
}
return None
def query_todo_tasks(agent_page_id=None):
"""查询 TODO 任务"""
logger.info(f"查询 {AGENT_ID} 的 TODO 任务...")
# 如果有 agent_page_id使用 Relation 过滤
filter_dict = {
"property": "状态",
"select": {
"equals": "TODO"
}
}
# 这里简化处理:查询所有 TODO 任务
# 后续应该根据执行者 Relation 过滤
try:
response = notion_request(
"POST",
f"/databases/{TASKS_DB_ID}/query",
json={"filter": filter_dict}
)
tasks = response.get("results", [])
logger.info(f"找到 {len(tasks)} 个 TODO 任务")
return tasks
except Exception as e:
logger.error(f"查询任务失败: {e}")
return []
def claim_task(task_id):
"""领取任务:将状态改为进行中"""
try:
notion_request(
"PATCH",
f"/pages/{task_id}",
json={
"properties": {
"状态": {
"select": {"name": "进行中"}
}
}
}
)
logger.info(f"✓ 领取任务成功: {task_id}")
return True
except Exception as e:
logger.error(f"领取任务失败: {e}")
return False
def complete_task(task_id, report_link):
"""完成任务:将状态改为待验收"""
try:
notion_request(
"PATCH",
f"/pages/{task_id}",
json={
"properties": {
"状态": {
"select": {"name": "待验收"}
},
"报告链接": {
"url": report_link
}
}
}
)
logger.info(f"✓ 完成任务: {task_id}")
return True
except Exception as e:
logger.error(f"完成任务失败: {e}")
return False
def execute_task(task):
"""执行任务的逻辑(可自定义)"""
# 获取任务信息
props = task.get("properties", {})
task_name = props.get("任务名", {}).get("title", [{}])[0].get("plain_text", "未命名任务")
task_id = task["id"]
logger.info(f"开始执行任务: {task_name}")
# 1. 领取任务
if not claim_task(task_id):
return False
# 2. 执行任务(这里只是示例,实际应根据任务类型执行不同操作)
# 模拟执行
time.sleep(2)
# 3. 完成任务(生成报告链接)
# 这里应该生成实际的 Obsidian 报告
report_link = f"https://example.com/report/{task_id}"
return complete_task(task_id, report_link)
def polling_loop():
"""轮询主循环"""
logger.info(f"🚀 Agent {AGENT_ID} 任务轮询启动")
logger.info(f"轮询间隔: {POLL_INTERVAL}")
# 获取 Agent 信息
agent_info = get_agent_info(AGENT_ID)
if agent_info:
logger.info(f"Agent 信息: {agent_info['name']} (状态: {agent_info['status']})")
else:
logger.warning(f"未找到 Agent: {AGENT_ID}")
while True:
try:
# 查询 TODO 任务
tasks = query_todo_tasks(None)
if tasks:
logger.info(f"发现 {len(tasks)} 个待处理任务")
for task in tasks:
execute_task(task)
else:
logger.debug("没有待处理任务")
except Exception as e:
logger.error(f"轮询异常: {e}")
time.sleep(POLL_INTERVAL)
def main():
"""主入口"""
if len(sys.argv) > 1:
global AGENT_ID
AGENT_ID = sys.argv[1]
if len(sys.argv) > 2:
global POLL_INTERVAL
POLL_INTERVAL = int(sys.argv[2])
polling_loop()
if __name__ == "__main__":
main()