Files
analysis_claude_code/s16_team_protocols/images/team-protocols-overview.svg
root a2374c5bd4 docs(s16): fix protocol flowchart — separate shutdown and plan approval flows
Split the single protocol row into two distinct flows:
- Protocol A (yellow): shutdown, initiated by Lead via request_shutdown
- Protocol B (blue): plan approval, initiated by Teammate via submit_plan

request_plan is now shown as a plain message (grey dashed box/arrow),
not a protocol action. review_plan is added to the diagram. All three
language SVGs updated with the same layout.

Closes #373
2026-07-29 00:14:40 +08:00

142 lines
11 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 660" font-family="system-ui, -apple-system, sans-serif">
<defs>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/><stop offset="100%" stop-color="#7c3aed"/>
</linearGradient>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#555"/>
</marker>
<marker id="arrow-purple" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#7c3aed"/>
</marker>
<marker id="arrow-green" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#16a34a"/>
</marker>
<marker id="arrow-red" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#dc2626"/>
</marker>
</defs>
<rect width="760" height="660" fill="#fafbfc" rx="8"/>
<rect x="0" y="0" width="760" height="44" fill="url(#header)" rx="8"/>
<rect x="0" y="36" width="760" height="8" fill="url(#header)"/>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Team Protocols — 请求-响应协议 + request_id 关联 + 状态机</text>
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s15 保留</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1"/>
<text x="158" y="66" fill="#7c3aed" font-size="10" font-weight="600">s16 新增</text>
<!-- Row 1: Lead Loop -->
<rect x="20" y="90" width="70" height="40" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="1.5"/>
<text x="55" y="114" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">turn</text>
<line x1="90" y1="110" x2="104" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="107" y="90" width="70" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="142" y="114" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="177" y1="110" x2="191" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="194" y="86" width="80" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="234" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt</text>
<line x1="274" y1="110" x2="288" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="291" y="86" width="70" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="326" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM</text>
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="80" width="356" height="60" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH核心工具集</text>
<text x="394" y="114" fill="#2563eb" font-size="8">bash · read · write · task(4) · spawn · send · inbox</text>
<text x="394" y="128" fill="#7c3aed" font-size="8" font-weight="700">★ request_shutdown · request_plan · review_plan</text>
<path d="M 734 110 L 748 110 L 748 150 L 55 150 L 55 130" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
<!-- Row 2: shutdown protocol -->
<rect x="30" y="176" width="700" height="90" rx="8" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<text x="380" y="196" fill="#92400e" font-size="11" font-weight="700" text-anchor="middle">协议 Ashutdown 流程Lead 发起 → 队友响应)</text>
<rect x="50" y="208" width="180" height="46" rx="6" fill="#fff" stroke="#d97706" stroke-width="1"/>
<text x="140" y="226" fill="#92400e" font-size="9" font-weight="600" text-anchor="middle">① Lead: request_shutdown</text>
<text x="140" y="242" fill="#6b7280" font-size="7" text-anchor="middle">new_request_id() → ProtocolState</text>
<line x1="230" y1="231" x2="254" y2="231" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="257" y="208" width="180" height="46" rx="6" fill="#fff" stroke="#d97706" stroke-width="1"/>
<text x="347" y="226" fill="#92400e" font-size="9" font-weight="600" text-anchor="middle">② 队友: handle_shutdown</text>
<text x="347" y="242" fill="#6b7280" font-size="7" text-anchor="middle">ack → shutdown_response</text>
<line x1="437" y1="231" x2="461" y2="231" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="464" y="208" width="180" height="46" rx="6" fill="#fff" stroke="#d97706" stroke-width="1"/>
<text x="554" y="226" fill="#92400e" font-size="9" font-weight="600" text-anchor="middle">③ Lead: consume_lead_inbox</text>
<text x="554" y="242" fill="#6b7280" font-size="7" text-anchor="middle">match_response(request_id) → ✓</text>
<!-- Row 3: plan approval protocol -->
<rect x="30" y="280" width="700" height="110" rx="8" fill="#dbeafe" stroke="#2563eb" stroke-width="1.5"/>
<text x="380" y="300" fill="#1e40af" font-size="11" font-weight="700" text-anchor="middle">协议 Bplan approval 流程(队友发起 → Lead 审批)</text>
<rect x="50" y="312" width="150" height="46" rx="6" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1"/>
<text x="125" y="330" fill="#475569" font-size="8" font-weight="600" text-anchor="middle">0. Lead: request_plan</text>
<text x="125" y="346" fill="#6b7280" font-size="7" text-anchor="middle">普通消息msg_type="message"</text>
<line x1="200" y1="335" x2="222" y2="335" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="4,3"/>
<rect x="225" y="312" width="160" height="46" rx="6" fill="#fff" stroke="#2563eb" stroke-width="1"/>
<text x="305" y="330" fill="#1e40af" font-size="8" font-weight="600" text-anchor="middle">① 队友: submit_plan</text>
<text x="305" y="346" fill="#6b7280" font-size="7" text-anchor="middle">plan_approval_request + request_id</text>
<line x1="385" y1="335" x2="407" y2="335" stroke="#2563eb" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="410" y="312" width="160" height="46" rx="6" fill="#fff" stroke="#2563eb" stroke-width="1"/>
<text x="490" y="330" fill="#1e40af" font-size="8" font-weight="600" text-anchor="middle">② Lead: review_plan</text>
<text x="490" y="346" fill="#6b7280" font-size="7" text-anchor="middle">plan_approval_response</text>
<line x1="570" y1="335" x2="592" y2="335" stroke="#2563eb" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="595" y="312" width="120" height="46" rx="6" fill="#fff" stroke="#2563eb" stroke-width="1"/>
<text x="655" y="330" fill="#1e40af" font-size="8" font-weight="600" text-anchor="middle">③ 队友: 收到结果</text>
<text x="655" y="346" fill="#6b7280" font-size="7" text-anchor="middle">[Plan approved/rejected]</text>
<text x="380" y="380" fill="#6b7280" font-size="8" text-anchor="middle">request_plan 是普通消息不是协议submit_plan 才是协议入口(由队友端创建 ProtocolState</text>
<!-- Row 4: State Machine + Storage -->
<rect x="30" y="406" width="340" height="85" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.5"/>
<text x="200" y="426" fill="#4c1d95" font-size="10" font-weight="700" text-anchor="middle">状态机(同一套,两种协议共用)</text>
<rect x="55" y="440" width="58" height="20" rx="4" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1"/>
<text x="84" y="454" fill="#475569" font-size="9" text-anchor="middle">pending</text>
<line x1="113" y1="450" x2="192" y2="450" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<text x="152" y="445" fill="#16a34a" font-size="8" font-weight="600" text-anchor="middle">approve</text>
<rect x="192" y="440" width="62" height="20" rx="4" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="223" y="454" fill="#166534" font-size="9" text-anchor="middle">approved</text>
<path d="M 84 460 L 84 478 L 128 478" fill="none" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<text x="76" y="472" fill="#dc2626" font-size="8" font-weight="600" text-anchor="end">reject</text>
<rect x="128" y="468" width="60" height="20" rx="4" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="158" y="482" fill="#991b1b" font-size="9" text-anchor="middle">rejected</text>
<rect x="400" y="406" width="330" height="85" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.5"/>
<text x="565" y="426" fill="#4c1d95" font-size="10" font-weight="700" text-anchor="middle">pending_requests 存储</text>
<text x="420" y="446" fill="#7c3aed" font-size="9">pending_requests: dict[str, ProtocolState]</text>
<text x="420" y="462" fill="#6b7280" font-size="8">request_id → {type, sender, status, created_at}</text>
<text x="420" y="478" fill="#6b7280" font-size="8">match_response: 按 request_id 找回对应请求</text>
<!-- Row 5: Two protocols same machine -->
<rect x="30" y="506" width="700" height="52" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="55" y="524" fill="#1e3a5f" font-size="10" font-weight="600">两种协议,同一套机制:</text>
<rect x="230" y="512" width="130" height="18" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="295" y="525" fill="#92400e" font-size="9" text-anchor="middle">shutdown_request</text>
<text x="368" y="525" fill="#475569" font-size="10"></text>
<rect x="390" y="512" width="140" height="18" rx="4" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="460" y="525" fill="#1e40af" font-size="9" text-anchor="middle">plan_approval_request</text>
<text x="55" y="548" fill="#6b7280" font-size="8">共用 pending → approved / rejected 状态机。新增协议类型 = 新的 msg_type不需要新状态机。request_id 关联请求和响应。</text>
<!-- Row 6: distinguish -->
<rect x="30" y="570" width="700" height="38" rx="6" fill="#f0fdf4" stroke="#16a34a" stroke-width="1"/>
<text x="55" y="588" fill="#166534" font-size="9" font-weight="600">区分:</text>
<text x="100" y="588" fill="#475569" font-size="9">request_plan 是普通消息msg_type="message"),由 lead 发送给队友提示去提交计划。</text>
<text x="55" y="602" fill="#475569" font-size="9">submit_plan 才是协议入口msg_type="plan_approval_request"),由队友主动发起,携带 request_id 写入 pending_requests。</text>
<!-- Bottom notes -->
<rect x="30" y="622" width="700" height="28" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="632" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="642" fill="#475569" font-size="10">s15: MessageBus + spawn_teammate + inbox</text>
<rect x="310" y="632" width="12" height="10" rx="2" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1"/>
<text x="330" y="642" fill="#475569" font-size="10">s16: request_id 协议 + dispatch + pending_requests + 状态机</text>
</svg>