|
@@ -100,8 +100,7 @@ def get_task(task_id: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
def can_start(task_id: str) -> bool:
|
|
def can_start(task_id: str) -> bool:
|
|
|
- """Check if all blockedBy dependencies are completed.
|
|
|
|
|
- Missing dependencies are treated as blocked."""
|
|
|
|
|
|
|
+ """检查所有 blockedBy 依赖是否已完成;缺失依赖视为阻塞。"""
|
|
|
task = load_task(task_id)
|
|
task = load_task(task_id)
|
|
|
for dep_id in task.blockedBy:
|
|
for dep_id in task.blockedBy:
|
|
|
if not _task_path(dep_id).exists():
|
|
if not _task_path(dep_id).exists():
|
|
@@ -114,31 +113,35 @@ def can_start(task_id: str) -> bool:
|
|
|
def claim_task(task_id: str, owner: str = "agent") -> str:
|
|
def claim_task(task_id: str, owner: str = "agent") -> str:
|
|
|
task = load_task(task_id)
|
|
task = load_task(task_id)
|
|
|
if task.status != "pending":
|
|
if task.status != "pending":
|
|
|
- return f"任务 {task_id} 当前状态为 {task.status},无法认领"
|
|
|
|
|
|
|
+ status = {"pending": "待处理", "in_progress": "进行中",
|
|
|
|
|
+ "completed": "已完成"}.get(task.status, task.status)
|
|
|
|
|
+ return f"任务 {task_id} 当前状态为 {status},无法认领"
|
|
|
if not can_start(task_id):
|
|
if not can_start(task_id):
|
|
|
deps = [d for d in task.blockedBy
|
|
deps = [d for d in task.blockedBy
|
|
|
if not _task_path(d).exists() or load_task(d).status != "completed"]
|
|
if not _task_path(d).exists() or load_task(d).status != "completed"]
|
|
|
- return f"Blocked by: {deps}"
|
|
|
|
|
|
|
+ return f"被阻塞于:{deps}"
|
|
|
task.owner = owner
|
|
task.owner = owner
|
|
|
task.status = "in_progress"
|
|
task.status = "in_progress"
|
|
|
save_task(task)
|
|
save_task(task)
|
|
|
- print(f" \033[36m[claim] {task.subject} → in_progress (owner: {owner})\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[36m[认领] {task.subject} → in_progress(负责人:{owner})\033[0m")
|
|
|
return f"已认领 {task.id} ({task.subject})"
|
|
return f"已认领 {task.id} ({task.subject})"
|
|
|
|
|
|
|
|
|
|
|
|
|
def complete_task(task_id: str) -> str:
|
|
def complete_task(task_id: str) -> str:
|
|
|
task = load_task(task_id)
|
|
task = load_task(task_id)
|
|
|
if task.status != "in_progress":
|
|
if task.status != "in_progress":
|
|
|
- return f"任务 {task_id} 当前状态为 {task.status},无法完成"
|
|
|
|
|
|
|
+ status = {"pending": "待处理", "in_progress": "进行中",
|
|
|
|
|
+ "completed": "已完成"}.get(task.status, task.status)
|
|
|
|
|
+ return f"任务 {task_id} 当前状态为 {status},无法完成"
|
|
|
task.status = "completed"
|
|
task.status = "completed"
|
|
|
save_task(task)
|
|
save_task(task)
|
|
|
unblocked = [t.subject for t in list_tasks()
|
|
unblocked = [t.subject for t in list_tasks()
|
|
|
if t.status == "pending" and t.blockedBy and can_start(t.id)]
|
|
if t.status == "pending" and t.blockedBy and can_start(t.id)]
|
|
|
- print(f" \033[32m[complete] {task.subject} ✓\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[32m[完成] {task.subject} ✓\033[0m")
|
|
|
msg = f"已完成 {task.id} ({task.subject})"
|
|
msg = f"已完成 {task.id} ({task.subject})"
|
|
|
if unblocked:
|
|
if unblocked:
|
|
|
msg += f"\n已解除阻塞:{', '.join(unblocked)}"
|
|
msg += f"\n已解除阻塞:{', '.join(unblocked)}"
|
|
|
- print(f" \033[33m[unblocked] {', '.join(unblocked)}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[33m[已解除阻塞] {', '.join(unblocked)}\033[0m")
|
|
|
return msg
|
|
return msg
|
|
|
|
|
|
|
|
|
|
|
|
@@ -161,7 +164,7 @@ def assemble_system_prompt(context: dict) -> str:
|
|
|
PROMPT_SECTIONS["workspace"]]
|
|
PROMPT_SECTIONS["workspace"]]
|
|
|
memories = context.get("memories", "")
|
|
memories = context.get("memories", "")
|
|
|
if memories:
|
|
if memories:
|
|
|
- sections.append(f"Relevant memories:\n{memories}")
|
|
|
|
|
|
|
+ sections.append(f"相关记忆:\n{memories}")
|
|
|
return "\n\n".join(sections)
|
|
return "\n\n".join(sections)
|
|
|
|
|
|
|
|
|
|
|
|
@@ -223,8 +226,8 @@ def run_write(path: str, content: str) -> str:
|
|
|
def run_create_task(subject: str, description: str = "",
|
|
def run_create_task(subject: str, description: str = "",
|
|
|
blockedBy: list[str] | None = None) -> str:
|
|
blockedBy: list[str] | None = None) -> str:
|
|
|
task = create_task(subject, description, blockedBy)
|
|
task = create_task(subject, description, blockedBy)
|
|
|
- deps = f" (blockedBy: {', '.join(blockedBy)})" if blockedBy else ""
|
|
|
|
|
- print(f" \033[34m[create] {task.subject}{deps}\033[0m")
|
|
|
|
|
|
|
+ deps = f"(依赖:{', '.join(blockedBy)})" if blockedBy else ""
|
|
|
|
|
+ print(f" \033[34m[创建] {task.subject}{deps}\033[0m")
|
|
|
return f"已创建 {task.id}: {task.subject}{deps}"
|
|
return f"已创建 {task.id}: {task.subject}{deps}"
|
|
|
|
|
|
|
|
|
|
|
|
@@ -236,10 +239,12 @@ def run_list_tasks() -> str:
|
|
|
for t in 个任务:
|
|
for t in 个任务:
|
|
|
icon = {"pending": "○", "in_progress": "●",
|
|
icon = {"pending": "○", "in_progress": "●",
|
|
|
"completed": "✓"}.get(t.status, "?")
|
|
"completed": "✓"}.get(t.status, "?")
|
|
|
- deps = f" (blockedBy: {', '.join(t.blockedBy)})" if t.blockedBy else ""
|
|
|
|
|
- owner = f" [{t.owner}]" if t.owner else ""
|
|
|
|
|
|
|
+ deps = f"(依赖:{', '.join(t.blockedBy)})" if t.blockedBy else ""
|
|
|
|
|
+ owner = f" [负责人:{t.owner}]" if t.owner else ""
|
|
|
|
|
+ status = {"pending": "待处理", "in_progress": "进行中",
|
|
|
|
|
+ "completed": "已完成"}.get(t.status, t.status)
|
|
|
lines.append(f" {icon} {t.id}: {t.subject} "
|
|
lines.append(f" {icon} {t.id}: {t.subject} "
|
|
|
- f"[{t.status}]{owner}{deps}")
|
|
|
|
|
|
|
+ f"[{status}]{owner}{deps}")
|
|
|
return "\n".join(lines)
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
|
|
|
@@ -304,7 +309,7 @@ def start_background_task(block) -> str:
|
|
|
"status": "running",
|
|
"status": "running",
|
|
|
}
|
|
}
|
|
|
threading.Thread(target=worker, daemon=True).start()
|
|
threading.Thread(target=worker, daemon=True).start()
|
|
|
- print(f" \033[33m[background] dispatched {bg_id}: {cmd[:40]}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[33m[后台] 已分发 {bg_id}: {cmd[:40]}\033[0m")
|
|
|
return bg_id
|
|
return bg_id
|
|
|
|
|
|
|
|
|
|
|
|
@@ -326,7 +331,7 @@ def collect_background_results() -> list[str]:
|
|
|
f" <command>{task['command']}</command>\n"
|
|
f" <command>{task['command']}</command>\n"
|
|
|
f" <summary>{summary}</summary>\n"
|
|
f" <summary>{summary}</summary>\n"
|
|
|
f"</task_notification>")
|
|
f"</task_notification>")
|
|
|
- print(f" \033[32m[background done] {bg_id}: "
|
|
|
|
|
|
|
+ print(f" \033[32m[后台完成] {bg_id}: "
|
|
|
f"{task['command'][:40]} ({len(output)} 个字符)\033[0m")
|
|
f"{task['command'][:40]} ({len(output)} 个字符)\033[0m")
|
|
|
return notifications
|
|
return notifications
|
|
|
|
|
|
|
@@ -338,9 +343,9 @@ MAILBOX_DIR.mkdir(exist_ok=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
class MessageBus:
|
|
class MessageBus:
|
|
|
- """File-based message bus. Each agent has a .jsonl inbox.
|
|
|
|
|
- Read is destructive: read_text + unlink (consumes messages).
|
|
|
|
|
- Teaching version: no file locking; real CC uses proper-lockfile."""
|
|
|
|
|
|
|
+ """基于文件的消息总线。每个 Agent 都有一个 .jsonl 收件箱。
|
|
|
|
|
+ 读取是破坏性的:read_text + unlink 会消费消息。
|
|
|
|
|
+ 教学版本不做文件锁;真实 CC 使用 proper-lockfile。"""
|
|
|
|
|
|
|
|
def send(self, from_agent: str, to_agent: str, content: str,
|
|
def send(self, from_agent: str, to_agent: str, content: str,
|
|
|
msg_type: str = "message", metadata: dict = None):
|
|
msg_type: str = "message", metadata: dict = None):
|
|
@@ -387,29 +392,28 @@ def new_request_id() -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
def match_response(response_type: str, request_id: str, approve: bool):
|
|
def match_response(response_type: str, request_id: str, approve: bool):
|
|
|
- """Correlate a response to the original request via request_id.
|
|
|
|
|
- Validates that response_type matches the request type."""
|
|
|
|
|
|
|
+ """通过 request_id 将响应关联到原始请求,并校验响应类型是否匹配。"""
|
|
|
state = pending_requests.get(request_id)
|
|
state = pending_requests.get(request_id)
|
|
|
if not state:
|
|
if not state:
|
|
|
- print(f" \033[31m[protocol] unknown request_id: {request_id}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[31m[协议] 未知 request_id: {request_id}\033[0m")
|
|
|
return
|
|
return
|
|
|
# 校验响应类型是否匹配请求类型
|
|
# 校验响应类型是否匹配请求类型
|
|
|
if state.type == "shutdown" and response_type != "shutdown_response":
|
|
if state.type == "shutdown" and response_type != "shutdown_response":
|
|
|
- print(f" \033[31m[protocol] type mismatch: expected shutdown_response, "
|
|
|
|
|
- f"got {response_type}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[31m[协议] 类型不匹配:期望 shutdown_response,"
|
|
|
|
|
+ f"实际得到 {response_type}\033[0m")
|
|
|
return
|
|
return
|
|
|
if state.type == "plan_approval" and response_type != "plan_approval_response":
|
|
if state.type == "plan_approval" and response_type != "plan_approval_response":
|
|
|
- print(f" \033[31m[protocol] type mismatch: expected plan_approval_response, "
|
|
|
|
|
- f"got {response_type}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[31m[协议] 类型不匹配:期望 plan_approval_response,"
|
|
|
|
|
+ f"实际得到 {response_type}\033[0m")
|
|
|
return
|
|
return
|
|
|
if state.status != "pending":
|
|
if state.status != "pending":
|
|
|
- print(f" \033[33m[protocol] {request_id} already {state.status}, "
|
|
|
|
|
- f"ignoring duplicate\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[33m[协议] {request_id} 已经是 {state.status},"
|
|
|
|
|
+ f"忽略重复响应\033[0m")
|
|
|
return
|
|
return
|
|
|
state.status = "approved" if approve else "rejected"
|
|
state.status = "approved" if approve else "rejected"
|
|
|
icon = "✓" if approve else "✗"
|
|
icon = "✓" if approve else "✗"
|
|
|
color = "32" if approve else "31"
|
|
color = "32" if approve else "31"
|
|
|
- print(f" \033[{color}m[protocol] {state.type} {icon} "
|
|
|
|
|
|
|
+ print(f" \033[{color}m[协议] {state.type} {icon} "
|
|
|
f"({request_id}: {state.status})\033[0m")
|
|
f"({request_id}: {state.status})\033[0m")
|
|
|
|
|
|
|
|
|
|
|
|
@@ -418,9 +422,8 @@ def match_response(response_type: str, request_id: str, approve: bool):
|
|
|
# 返回前通过 match_response 路由协议响应。
|
|
# 返回前通过 match_response 路由协议响应。
|
|
|
|
|
|
|
|
def consume_lead_inbox(route_protocol: bool = True) -> list[dict]:
|
|
def consume_lead_inbox(route_protocol: bool = True) -> list[dict]:
|
|
|
- """Read Lead's inbox. Route protocol responses, return all messages.
|
|
|
|
|
- Called by both run_check_inbox() and main loop to avoid
|
|
|
|
|
- messages being consumed without protocol routing."""
|
|
|
|
|
|
|
+ """读取 Lead 收件箱,路由协议响应,并返回所有消息。
|
|
|
|
|
+ run_check_inbox() 和主循环都会调用,避免消息被消费却没有经过协议路由。"""
|
|
|
msgs = BUS.read_inbox("lead")
|
|
msgs = BUS.read_inbox("lead")
|
|
|
if not msgs:
|
|
if not msgs:
|
|
|
return []
|
|
return []
|
|
@@ -438,9 +441,9 @@ def consume_lead_inbox(route_protocol: bool = True) -> list[dict]:
|
|
|
# ── 队友线程 (s16: 空闲循环 + 分发) ──
|
|
# ── 队友线程 (s16: 空闲循环 + 分发) ──
|
|
|
|
|
|
|
|
def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
- """Spawn a teammate agent in a background thread.
|
|
|
|
|
- Uses idle loop: 等待 each LLM 轮次, waits for inbox messages
|
|
|
|
|
- (shutdown_request, new task) instead of exiting."""
|
|
|
|
|
|
|
+ """在后台线程中启动队友 Agent。
|
|
|
|
|
+ 队友使用空闲循环:每轮 LLM 后等待收件箱消息
|
|
|
|
|
+ (shutdown_request 或新任务),而不是直接退出。"""
|
|
|
if name in active_teammates:
|
|
if name in active_teammates:
|
|
|
return f"队友 '{name}' 已存在"
|
|
return f"队友 '{name}' 已存在"
|
|
|
|
|
|
|
@@ -449,8 +452,7 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
f"检查收件箱中的协议消息(shutdown_request 等)。")
|
|
f"检查收件箱中的协议消息(shutdown_request 等)。")
|
|
|
|
|
|
|
|
def handle_inbox_message(name: str, msg: dict, messages: list) -> bool:
|
|
def handle_inbox_message(name: str, msg: dict, messages: list) -> bool:
|
|
|
- """Dispatch incoming protocol messages by type.
|
|
|
|
|
- Returns True if teammate should stop."""
|
|
|
|
|
|
|
+ """按类型分发收到的协议消息。返回 True 表示队友应停止。"""
|
|
|
msg_type = msg.get("type", "message")
|
|
msg_type = msg.get("type", "message")
|
|
|
meta = msg.get("metadata", {})
|
|
meta = msg.get("metadata", {})
|
|
|
req_id = meta.get("request_id", "")
|
|
req_id = meta.get("request_id", "")
|
|
@@ -459,7 +461,7 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
BUS.send(name, "lead", "正在平滑关闭。",
|
|
BUS.send(name, "lead", "正在平滑关闭。",
|
|
|
"shutdown_response",
|
|
"shutdown_response",
|
|
|
{"request_id": req_id, "approve": True})
|
|
{"request_id": req_id, "approve": True})
|
|
|
- print(f" \033[35m[protocol] {name} approved shutdown "
|
|
|
|
|
|
|
+ print(f" \033[35m[协议] {name} 已批准关闭 "
|
|
|
f"({req_id})\033[0m")
|
|
f"({req_id})\033[0m")
|
|
|
return True # 停止循环
|
|
return True # 停止循环
|
|
|
|
|
|
|
@@ -491,7 +493,7 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
"content": {"type": "string"}},
|
|
"content": {"type": "string"}},
|
|
|
"required": ["path", "content"]}},
|
|
"required": ["path", "content"]}},
|
|
|
{"name": "send_message",
|
|
{"name": "send_message",
|
|
|
- "description": "Send message to another agent.",
|
|
|
|
|
|
|
+ "description": "向另一个 Agent 发送消息。",
|
|
|
"input_schema": {"type": "object",
|
|
"input_schema": {"type": "object",
|
|
|
"properties": {"to": {"type": "string"},
|
|
"properties": {"to": {"type": "string"},
|
|
|
"content": {"type": "string"}},
|
|
"content": {"type": "string"}},
|
|
@@ -505,7 +507,7 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
sub_handlers = {
|
|
sub_handlers = {
|
|
|
"bash": run_bash, "read_file": run_read, "write_file": run_write,
|
|
"bash": run_bash, "read_file": run_read, "write_file": run_write,
|
|
|
"send_message": lambda to, content: (BUS.send(name, to, content),
|
|
"send_message": lambda to, content: (BUS.send(name, to, content),
|
|
|
- "Sent")[1],
|
|
|
|
|
|
|
+ "已发送")[1],
|
|
|
"submit_plan": lambda plan: _teammate_submit_plan(name, plan),
|
|
"submit_plan": lambda plan: _teammate_submit_plan(name, plan),
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -587,23 +589,21 @@ def spawn_teammate_thread(name: str, role: str, prompt: str) -> str:
|
|
|
break
|
|
break
|
|
|
BUS.send(name, "lead", summary, "result")
|
|
BUS.send(name, "lead", summary, "result")
|
|
|
active_teammates.pop(name, None)
|
|
active_teammates.pop(name, None)
|
|
|
- print(f" \033[32m[teammate] {name} finished\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[32m[队友] {name} 已完成\033[0m")
|
|
|
|
|
|
|
|
active_teammates[name] = True
|
|
active_teammates[name] = True
|
|
|
threading.Thread(target=run, daemon=True).start()
|
|
threading.Thread(target=run, daemon=True).start()
|
|
|
- print(f" \033[36m[teammate] {name} spawned as {role}\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[36m[队友] {name} 已作为 {role} 启动\033[0m")
|
|
|
return f"队友 '{name}' 已启动为 {role}"
|
|
return f"队友 '{name}' 已启动为 {role}"
|
|
|
|
|
|
|
|
|
|
|
|
|
def _teammate_submit_plan(from_name: str, plan: str) -> str:
|
|
def _teammate_submit_plan(from_name: str, plan: str) -> str:
|
|
|
- """Teammate submits a plan to Lead for approval.
|
|
|
|
|
-
|
|
|
|
|
- Note: This is a protocol-level request, not a code-level gate.
|
|
|
|
|
- After submitting, the teammate's thread 继续s running — it can
|
|
|
|
|
- still call bash/write/etc. Real enforcement relies on the model
|
|
|
|
|
- waiting for the approval response before acting. Code-level tool
|
|
|
|
|
- gating would require blocking the teammate's tool dispatch until
|
|
|
|
|
- approval arrives.
|
|
|
|
|
|
|
+ """队友向 Lead 提交计划以供审批。
|
|
|
|
|
+
|
|
|
|
|
+ 注意:这是协议层请求,不是代码层闸门。
|
|
|
|
|
+ 提交后,队友线程仍会继续运行,仍然可以调用 bash/write 等工具。
|
|
|
|
|
+ 真实约束依赖模型在行动前等待审批响应。
|
|
|
|
|
+ 若要做代码层工具闸门,需要在审批到达前阻塞队友的工具分发。
|
|
|
"""
|
|
"""
|
|
|
req_id = new_request_id()
|
|
req_id = new_request_id()
|
|
|
pending_requests[req_id] = ProtocolState(
|
|
pending_requests[req_id] = ProtocolState(
|
|
@@ -616,7 +616,7 @@ def _teammate_submit_plan(from_name: str, plan: str) -> str:
|
|
|
return f"计划已提交({req_id})。正在等待审批..."
|
|
return f"计划已提交({req_id})。正在等待审批..."
|
|
|
|
|
|
|
|
|
|
|
|
|
-# ── Lead Protocol 工具 (s16 新增) ──
|
|
|
|
|
|
|
+# ── Lead 协议工具 (s16 新增) ──
|
|
|
|
|
|
|
|
def run_request_shutdown(teammate: str) -> str:
|
|
def run_request_shutdown(teammate: str) -> str:
|
|
|
req_id = new_request_id()
|
|
req_id = new_request_id()
|
|
@@ -627,13 +627,13 @@ def run_request_shutdown(teammate: str) -> str:
|
|
|
BUS.send("lead", teammate, "请平滑关闭。",
|
|
BUS.send("lead", teammate, "请平滑关闭。",
|
|
|
"shutdown_request",
|
|
"shutdown_request",
|
|
|
{"request_id": req_id})
|
|
{"request_id": req_id})
|
|
|
- print(f" \033[35m[protocol] shutdown_request → {teammate} "
|
|
|
|
|
|
|
+ print(f" \033[35m[协议] shutdown_request → {teammate} "
|
|
|
f"({req_id})\033[0m")
|
|
f"({req_id})\033[0m")
|
|
|
return f"已向 {teammate} 发送关闭请求(req: {req_id})"
|
|
return f"已向 {teammate} 发送关闭请求(req: {req_id})"
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_request_plan(teammate: str, task: str) -> str:
|
|
def run_request_plan(teammate: str, task: str) -> str:
|
|
|
- """Lead asks a teammate to submit a plan for a task."""
|
|
|
|
|
|
|
+ """Lead 要求队友为指定任务提交计划。"""
|
|
|
BUS.send("lead", teammate, f"请为以下任务提交计划:{task}",
|
|
BUS.send("lead", teammate, f"请为以下任务提交计划:{task}",
|
|
|
"message")
|
|
"message")
|
|
|
return f"已要求 {teammate} 提交计划"
|
|
return f"已要求 {teammate} 提交计划"
|
|
@@ -646,11 +646,11 @@ def run_review_plan(request_id: str, approve: bool, feedback: str = "") -> str:
|
|
|
if state.status != "pending":
|
|
if state.status != "pending":
|
|
|
return f"请求 {request_id} 已经是 {state.status}"
|
|
return f"请求 {request_id} 已经是 {state.status}"
|
|
|
state.status = "approved" if approve else "rejected"
|
|
state.status = "approved" if approve else "rejected"
|
|
|
- BUS.send("lead", state.sender, feedback or ("Approved" if approve else "Rejected"),
|
|
|
|
|
|
|
+ BUS.send("lead", state.sender, feedback or ("已批准" if approve else "已拒绝"),
|
|
|
"plan_approval_response",
|
|
"plan_approval_response",
|
|
|
{"request_id": request_id, "approve": approve})
|
|
{"request_id": request_id, "approve": approve})
|
|
|
icon = "✓" if approve else "✗"
|
|
icon = "✓" if approve else "✗"
|
|
|
- print(f" \033[32m[protocol] plan {icon} ({request_id})\033[0m")
|
|
|
|
|
|
|
+ print(f" \033[32m[协议] 计划 {icon} ({request_id})\033[0m")
|
|
|
return f"计划已{'批准' if approve else '拒绝'}({request_id})"
|
|
return f"计划已{'批准' if approve else '拒绝'}({request_id})"
|
|
|
|
|
|
|
|
|
|
|
|
@@ -754,7 +754,7 @@ TOOLS = [
|
|
|
"prompt": {"type": "string"}},
|
|
"prompt": {"type": "string"}},
|
|
|
"required": ["name", "role", "prompt"]}},
|
|
"required": ["name", "role", "prompt"]}},
|
|
|
{"name": "send_message",
|
|
{"name": "send_message",
|
|
|
- "description": "Send message to a teammate via MessageBus.",
|
|
|
|
|
|
|
+ "description": "通过 MessageBus 向队友发送消息。",
|
|
|
"input_schema": {"type": "object",
|
|
"input_schema": {"type": "object",
|
|
|
"properties": {"to": {"type": "string"},
|
|
"properties": {"to": {"type": "string"},
|
|
|
"content": {"type": "string"}},
|
|
"content": {"type": "string"}},
|
|
@@ -788,7 +788,7 @@ TOOLS = [
|
|
|
# ── 上下文 ──
|
|
# ── 上下文 ──
|
|
|
|
|
|
|
|
def update_context(context: dict, messages: list) -> dict:
|
|
def update_context(context: dict, messages: list) -> dict:
|
|
|
- """Derive context from real state."""
|
|
|
|
|
|
|
+ """从真实状态推导上下文。"""
|
|
|
memories = ""
|
|
memories = ""
|
|
|
if MEMORY_INDEX.exists():
|
|
if MEMORY_INDEX.exists():
|
|
|
content = MEMORY_INDEX.read_text().strip()
|
|
content = MEMORY_INDEX.read_text().strip()
|
|
@@ -830,7 +830,7 @@ def agent_loop(messages: list, context: dict):
|
|
|
bg_id = start_background_task(block)
|
|
bg_id = start_background_task(block)
|
|
|
results.append({"type": "tool_result",
|
|
results.append({"type": "tool_result",
|
|
|
"tool_use_id": block.id,
|
|
"tool_use_id": block.id,
|
|
|
- "content": f"[Background task {bg_id} started] "
|
|
|
|
|
|
|
+ "content": f"[后台任务 {bg_id} 已启动] "
|
|
|
f"完成后结果将可用。"})
|
|
f"完成后结果将可用。"})
|
|
|
else:
|
|
else:
|
|
|
output = execute_tool(block)
|
|
output = execute_tool(block)
|
|
@@ -878,5 +878,5 @@ if __name__ == "__main__":
|
|
|
f"来自 {m['from']}: {m['content'][:200]}" for m in inbox_msgs)
|
|
f"来自 {m['from']}: {m['content'][:200]}" for m in inbox_msgs)
|
|
|
history.append({"role": "user",
|
|
history.append({"role": "user",
|
|
|
"content": f"[收件箱]\n{inbox_text}"})
|
|
"content": f"[收件箱]\n{inbox_text}"})
|
|
|
- print(f"\n\033[33m[Inbox: {len(inbox_msgs)} 条消息已注入]\033[0m")
|
|
|
|
|
|
|
+ print(f"\n\033[33m[收件箱:已注入 {len(inbox_msgs)} 条消息]\033[0m")
|
|
|
print()
|
|
print()
|