refactor: streamline the course to 17 lessons
@@ -0,0 +1,107 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 620" 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="#0891b2"/>
|
||||
</linearGradient>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#475569"/>
|
||||
</marker>
|
||||
<marker id="arrow-cyan" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-green" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#16a34a"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="760" height="620" rx="8" fill="#fafbfc"/>
|
||||
<rect width="760" height="44" rx="8" fill="url(#header)"/>
|
||||
<rect y="36" width="760" height="8" fill="url(#header)"/>
|
||||
<text x="380" y="28" text-anchor="middle" fill="#fff" font-size="15" font-weight="700">Agent Teams — One Team Harness</text>
|
||||
|
||||
<!-- User confirmation, Lead, and typed control -->
|
||||
<rect x="28" y="82" width="140" height="62" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="98" y="106" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">User</text>
|
||||
<text x="98" y="124" text-anchor="middle" fill="#64748b" font-size="9">confirm team first</text>
|
||||
|
||||
<line x1="168" y1="113" x2="220" y2="113" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<rect x="220" y="72" width="300" height="82" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.8"/>
|
||||
<text x="370" y="96" text-anchor="middle" fill="#1e3a5f" font-size="12" font-weight="700">Lead Agent Loop</text>
|
||||
<text x="370" y="116" text-anchor="middle" fill="#475569" font-size="9">user conversation · task creation · team coordination</text>
|
||||
<text x="370" y="134" text-anchor="middle" fill="#2563eb" font-size="9" font-weight="600">spawn · send · worktree create · plan review</text>
|
||||
|
||||
<line x1="520" y1="113" x2="570" y2="113" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="570" y="82" width="162" height="62" rx="8" fill="#fffbeb" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="651" y="105" text-anchor="middle" fill="#92400e" font-size="10" font-weight="700">Typed control</text>
|
||||
<text x="651" y="122" text-anchor="middle" fill="#a16207" font-size="8.5">request_id · shutdown</text>
|
||||
<text x="651" y="136" text-anchor="middle" fill="#a16207" font-size="8.5">plan approval gate</text>
|
||||
|
||||
<!-- Connect top row to MessageBus; endpoints meet box edges -->
|
||||
<line x1="370" y1="154" x2="370" y2="190" stroke="#0891b2" stroke-width="1.8" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="651" y1="144" x2="651" y2="190" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="60" y="190" width="640" height="44" rx="22" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="380" y="209" text-anchor="middle" fill="#0e7490" font-size="11" font-weight="700">MessageBus · .mailboxes/<name>.jsonl</text>
|
||||
<text x="380" y="225" text-anchor="middle" fill="#0f766e" font-size="8.5">runtime delivery · ordinary messages · result · idle_notification · control events</text>
|
||||
|
||||
<!-- MessageBus and teammate loops -->
|
||||
<line x1="118" y1="234" x2="118" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="348" y1="234" x2="348" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="578" y1="234" x2="578" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="182" y1="282" x2="182" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="412" y1="282" x2="412" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="642" y1="282" x2="642" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
|
||||
<rect x="40" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="150" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">Teammate: config</text>
|
||||
<text x="150" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">independent prompt · messages · tools</text>
|
||||
<text x="150" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="150" y="356" text-anchor="middle" fill="#64748b" font-size="8">direct message returns to WORK</text>
|
||||
|
||||
<rect x="270" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="380" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">Teammate: auth</text>
|
||||
<text x="380" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">independent prompt · messages · tools</text>
|
||||
<text x="380" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="380" y="356" text-anchor="middle" fill="#64748b" font-size="8">claimed task returns to WORK</text>
|
||||
|
||||
<rect x="500" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="610" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">Teammate: tests</text>
|
||||
<text x="610" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">independent prompt · messages · tools</text>
|
||||
<text x="610" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="610" y="356" text-anchor="middle" fill="#64748b" font-size="8">shutdown exits the loop</text>
|
||||
|
||||
<!-- IDLE task discovery -->
|
||||
<line x1="150" y1="364" x2="150" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="380" y1="364" x2="380" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="610" y1="364" x2="610" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
<rect x="60" y="404" width="640" height="54" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="380" y="425" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">Shared Task Board · .tasks/</text>
|
||||
<text x="380" y="444" text-anchor="middle" fill="#475569" font-size="9">IDLE: wait for mailbox first → scan ready tasks → claim atomically → reuse WORK loop</text>
|
||||
|
||||
<!-- Task binding selects cwd -->
|
||||
<line x1="380" y1="458" x2="380" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="540" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="220" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<line x1="540" y1="482" x2="540" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<rect x="311" y="468" width="138" height="18" rx="4" fill="#fafbfc"/>
|
||||
<text x="380" y="480" text-anchor="middle" fill="#475569" font-size="8.5" font-weight="600">Task.worktree selects cwd</text>
|
||||
|
||||
<rect x="60" y="506" width="300" height="66" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="210" y="529" text-anchor="middle" fill="#1e3a5f" font-size="10.5" font-weight="700">No worktree: repository WORKDIR</text>
|
||||
<text x="210" y="548" text-anchor="middle" fill="#475569" font-size="8.5">task.worktree is null</text>
|
||||
<text x="210" y="562" text-anchor="middle" fill="#64748b" font-size="8">same behavior as earlier lessons</text>
|
||||
|
||||
<rect x="400" y="506" width="300" height="66" rx="8" fill="#fff7ed" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="550" y="529" text-anchor="middle" fill="#92400e" font-size="10.5" font-weight="700">Opt-in: .worktrees/<name></text>
|
||||
<text x="550" y="548" text-anchor="middle" fill="#a16207" font-size="8.5">separate checkout + retained wt/<name> branch</text>
|
||||
<text x="550" y="562" text-anchor="middle" fill="#78716c" font-size="8">working-directory isolation, not a sandbox</text>
|
||||
|
||||
<rect x="60" y="590" width="640" height="20" rx="5" fill="#ecfdf5" stroke="#bbf7d0"/>
|
||||
<text x="380" y="604" text-anchor="middle" fill="#166534" font-size="8.5" font-weight="600">Only successful task completion clears the teammate assignment and cwd.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
@@ -0,0 +1,107 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 620" 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="#0891b2"/>
|
||||
</linearGradient>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#475569"/>
|
||||
</marker>
|
||||
<marker id="arrow-cyan" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-green" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#16a34a"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="760" height="620" rx="8" fill="#fafbfc"/>
|
||||
<rect width="760" height="44" rx="8" fill="url(#header)"/>
|
||||
<rect y="36" width="760" height="8" fill="url(#header)"/>
|
||||
<text x="380" y="28" text-anchor="middle" fill="#fff" font-size="15" font-weight="700">Agent Teams — 1 つの Team Harness</text>
|
||||
|
||||
<!-- ユーザー確認、Lead、制御プロトコル -->
|
||||
<rect x="28" y="82" width="140" height="62" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="98" y="106" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">ユーザー</text>
|
||||
<text x="98" y="124" text-anchor="middle" fill="#64748b" font-size="9">先にチームを確認</text>
|
||||
|
||||
<line x1="168" y1="113" x2="220" y2="113" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<rect x="220" y="72" width="300" height="82" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.8"/>
|
||||
<text x="370" y="96" text-anchor="middle" fill="#1e3a5f" font-size="12" font-weight="700">Lead Agent Loop</text>
|
||||
<text x="370" y="116" text-anchor="middle" fill="#475569" font-size="9">ユーザー対話 · タスク作成 · チーム調整</text>
|
||||
<text x="370" y="134" text-anchor="middle" fill="#2563eb" font-size="9" font-weight="600">起動 · 送信 · worktree 作成 · 計画レビュー</text>
|
||||
|
||||
<line x1="520" y1="113" x2="570" y2="113" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="570" y="82" width="162" height="62" rx="8" fill="#fffbeb" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="651" y="105" text-anchor="middle" fill="#92400e" font-size="10" font-weight="700">型付き制御</text>
|
||||
<text x="651" y="122" text-anchor="middle" fill="#a16207" font-size="8.5">request_id · shutdown</text>
|
||||
<text x="651" y="136" text-anchor="middle" fill="#a16207" font-size="8.5">計画承認ゲート</text>
|
||||
|
||||
<!-- 線の端点はコンポーネントの境界に合わせる -->
|
||||
<line x1="370" y1="154" x2="370" y2="190" stroke="#0891b2" stroke-width="1.8" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="651" y1="144" x2="651" y2="190" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="60" y="190" width="640" height="44" rx="22" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="380" y="209" text-anchor="middle" fill="#0e7490" font-size="11" font-weight="700">MessageBus · .mailboxes/<name>.jsonl</text>
|
||||
<text x="380" y="225" text-anchor="middle" fill="#0f766e" font-size="8.5">ランタイム配信 · 通常メッセージ · result · idle_notification · 制御イベント</text>
|
||||
|
||||
<!-- MessageBus とチームメイトループ -->
|
||||
<line x1="118" y1="234" x2="118" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="348" y1="234" x2="348" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="578" y1="234" x2="578" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="182" y1="282" x2="182" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="412" y1="282" x2="412" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="642" y1="282" x2="642" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
|
||||
<rect x="40" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="150" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">チームメイト:config</text>
|
||||
<text x="150" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立した prompt · messages · tools</text>
|
||||
<text x="150" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="150" y="356" text-anchor="middle" fill="#64748b" font-size="8">直接メッセージで WORK へ戻る</text>
|
||||
|
||||
<rect x="270" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="380" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">チームメイト:auth</text>
|
||||
<text x="380" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立した prompt · messages · tools</text>
|
||||
<text x="380" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="380" y="356" text-anchor="middle" fill="#64748b" font-size="8">Claim したタスクで WORK へ戻る</text>
|
||||
|
||||
<rect x="500" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="610" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">チームメイト:tests</text>
|
||||
<text x="610" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立した prompt · messages · tools</text>
|
||||
<text x="610" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="610" y="356" text-anchor="middle" fill="#64748b" font-size="8">shutdown でループ終了</text>
|
||||
|
||||
<!-- IDLE のタスク発見 -->
|
||||
<line x1="150" y1="364" x2="150" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="380" y1="364" x2="380" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="610" y1="364" x2="610" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
<rect x="60" y="404" width="640" height="54" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="380" y="425" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">共有タスクボード · .tasks/</text>
|
||||
<text x="380" y="444" text-anchor="middle" fill="#475569" font-size="9">IDLE:受信箱を先に待つ → ready task を走査 → アトミックに Claim → WORK を再利用</text>
|
||||
|
||||
<!-- タスクの紐付けが cwd を選ぶ -->
|
||||
<line x1="380" y1="458" x2="380" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="540" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="220" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<line x1="540" y1="482" x2="540" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<rect x="311" y="468" width="138" height="18" rx="4" fill="#fafbfc"/>
|
||||
<text x="380" y="480" text-anchor="middle" fill="#475569" font-size="8.5" font-weight="600">Task.worktree が cwd を選択</text>
|
||||
|
||||
<rect x="60" y="506" width="300" height="66" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="210" y="529" text-anchor="middle" fill="#1e3a5f" font-size="10.5" font-weight="700">worktree なし:リポジトリ WORKDIR</text>
|
||||
<text x="210" y="548" text-anchor="middle" fill="#475569" font-size="8.5">task.worktree は null</text>
|
||||
<text x="210" y="562" text-anchor="middle" fill="#64748b" font-size="8">以前のレッスンと同じ動作</text>
|
||||
|
||||
<rect x="400" y="506" width="300" height="66" rx="8" fill="#fff7ed" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="550" y="529" text-anchor="middle" fill="#92400e" font-size="10.5" font-weight="700">任意:.worktrees/<name></text>
|
||||
<text x="550" y="548" text-anchor="middle" fill="#a16207" font-size="8.5">独立 checkout + wt/<name> branch を保持</text>
|
||||
<text x="550" y="562" text-anchor="middle" fill="#78716c" font-size="8">作業ディレクトリの分離であり sandbox ではない</text>
|
||||
|
||||
<rect x="60" y="590" width="640" height="20" rx="5" fill="#ecfdf5" stroke="#bbf7d0"/>
|
||||
<text x="380" y="604" text-anchor="middle" fill="#166534" font-size="8.5" font-weight="600">タスク完了に成功した時だけ、チームメイトの assignment と cwd を解除する。</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1,107 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 620" 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="#0891b2"/>
|
||||
</linearGradient>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#475569"/>
|
||||
</marker>
|
||||
<marker id="arrow-cyan" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-green" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#16a34a"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="760" height="620" rx="8" fill="#fafbfc"/>
|
||||
<rect width="760" height="44" rx="8" fill="url(#header)"/>
|
||||
<rect y="36" width="760" height="8" fill="url(#header)"/>
|
||||
<text x="380" y="28" text-anchor="middle" fill="#fff" font-size="15" font-weight="700">Agent Teams — 一套 Team Harness</text>
|
||||
|
||||
<!-- 用户确认、Lead 与控制协议 -->
|
||||
<rect x="28" y="82" width="140" height="62" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="98" y="106" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">用户</text>
|
||||
<text x="98" y="124" text-anchor="middle" fill="#64748b" font-size="9">先确认团队方案</text>
|
||||
|
||||
<line x1="168" y1="113" x2="220" y2="113" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
|
||||
<rect x="220" y="72" width="300" height="82" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.8"/>
|
||||
<text x="370" y="96" text-anchor="middle" fill="#1e3a5f" font-size="12" font-weight="700">Lead Agent Loop</text>
|
||||
<text x="370" y="116" text-anchor="middle" fill="#475569" font-size="9">用户对话 · 创建任务 · 协调团队</text>
|
||||
<text x="370" y="134" text-anchor="middle" fill="#2563eb" font-size="9" font-weight="600">启动 · 发消息 · 创建 worktree · 审批计划</text>
|
||||
|
||||
<line x1="520" y1="113" x2="570" y2="113" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="570" y="82" width="162" height="62" rx="8" fill="#fffbeb" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="651" y="105" text-anchor="middle" fill="#92400e" font-size="10" font-weight="700">类型化控制</text>
|
||||
<text x="651" y="122" text-anchor="middle" fill="#a16207" font-size="8.5">request_id · shutdown</text>
|
||||
<text x="651" y="136" text-anchor="middle" fill="#a16207" font-size="8.5">计划审批闸门</text>
|
||||
|
||||
<!-- 连线端点精确落在组件边缘 -->
|
||||
<line x1="370" y1="154" x2="370" y2="190" stroke="#0891b2" stroke-width="1.8" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="651" y1="144" x2="651" y2="190" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrow-amber)"/>
|
||||
|
||||
<rect x="60" y="190" width="640" height="44" rx="22" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="380" y="209" text-anchor="middle" fill="#0e7490" font-size="11" font-weight="700">MessageBus · .mailboxes/<name>.jsonl</text>
|
||||
<text x="380" y="225" text-anchor="middle" fill="#0f766e" font-size="8.5">运行时投递 · 普通消息 · result · idle_notification · 控制事件</text>
|
||||
|
||||
<!-- MessageBus 与队友循环 -->
|
||||
<line x1="118" y1="234" x2="118" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="348" y1="234" x2="348" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="578" y1="234" x2="578" y2="282" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="182" y1="282" x2="182" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="412" y1="282" x2="412" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="642" y1="282" x2="642" y2="234" stroke="#0891b2" stroke-width="1.2" stroke-dasharray="4 3" marker-end="url(#arrow-cyan)"/>
|
||||
|
||||
<rect x="40" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="150" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">队友:config</text>
|
||||
<text x="150" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立 prompt · messages · tools</text>
|
||||
<text x="150" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="150" y="356" text-anchor="middle" fill="#64748b" font-size="8">直接消息使其回到 WORK</text>
|
||||
|
||||
<rect x="270" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="380" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">队友:auth</text>
|
||||
<text x="380" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立 prompt · messages · tools</text>
|
||||
<text x="380" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="380" y="356" text-anchor="middle" fill="#64748b" font-size="8">认领任务使其回到 WORK</text>
|
||||
|
||||
<rect x="500" y="282" width="220" height="82" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="610" y="305" text-anchor="middle" fill="#166534" font-size="10.5" font-weight="700">队友:tests</text>
|
||||
<text x="610" y="324" text-anchor="middle" fill="#15803d" font-size="8.5">独立 prompt · messages · tools</text>
|
||||
<text x="610" y="342" text-anchor="middle" fill="#475569" font-size="8.5">WORK → result → IDLE</text>
|
||||
<text x="610" y="356" text-anchor="middle" fill="#64748b" font-size="8">shutdown 结束循环</text>
|
||||
|
||||
<!-- IDLE 时发现任务 -->
|
||||
<line x1="150" y1="364" x2="150" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="380" y1="364" x2="380" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
<line x1="610" y1="364" x2="610" y2="404" stroke="#16a34a" stroke-width="1.5" marker-end="url(#arrow-green)"/>
|
||||
|
||||
<rect x="60" y="404" width="640" height="54" rx="8" fill="#f8fafc" stroke="#64748b" stroke-width="1.5"/>
|
||||
<text x="380" y="425" text-anchor="middle" fill="#334155" font-size="11" font-weight="700">共享任务板 · .tasks/</text>
|
||||
<text x="380" y="444" text-anchor="middle" fill="#475569" font-size="9">IDLE:先等收件箱 → 扫描 ready task → 原子认领 → 复用 WORK 循环</text>
|
||||
|
||||
<!-- 任务绑定选择 cwd -->
|
||||
<line x1="380" y1="458" x2="380" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="540" y2="482" stroke="#475569" stroke-width="1.5"/>
|
||||
<line x1="220" y1="482" x2="220" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<line x1="540" y1="482" x2="540" y2="506" stroke="#475569" stroke-width="1.5" marker-end="url(#arrow)"/>
|
||||
<rect x="311" y="468" width="138" height="18" rx="4" fill="#fafbfc"/>
|
||||
<text x="380" y="480" text-anchor="middle" fill="#475569" font-size="8.5" font-weight="600">Task.worktree 选择 cwd</text>
|
||||
|
||||
<rect x="60" y="506" width="300" height="66" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
|
||||
<text x="210" y="529" text-anchor="middle" fill="#1e3a5f" font-size="10.5" font-weight="700">无 worktree:仓库 WORKDIR</text>
|
||||
<text x="210" y="548" text-anchor="middle" fill="#475569" font-size="8.5">task.worktree 为 null</text>
|
||||
<text x="210" y="562" text-anchor="middle" fill="#64748b" font-size="8">行为与前面章节一致</text>
|
||||
|
||||
<rect x="400" y="506" width="300" height="66" rx="8" fill="#fff7ed" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="550" y="529" text-anchor="middle" fill="#92400e" font-size="10.5" font-weight="700">按需开启:.worktrees/<name></text>
|
||||
<text x="550" y="548" text-anchor="middle" fill="#a16207" font-size="8.5">独立 checkout + 保留 wt/<name> 分支</text>
|
||||
<text x="550" y="562" text-anchor="middle" fill="#78716c" font-size="8">只隔开工作目录,不是安全沙箱</text>
|
||||
|
||||
<rect x="60" y="590" width="640" height="20" rx="5" fill="#ecfdf5" stroke="#bbf7d0"/>
|
||||
<text x="380" y="604" text-anchor="middle" fill="#166534" font-size="8.5" font-weight="600">只有任务成功完成后,运行时才会清除队友的 assignment 和 cwd。</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.4 KiB |
@@ -0,0 +1,141 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 664" 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="664" 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-Response + request_id Correlation + State Machine</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">Team runtime</text>
|
||||
<rect x="160" y="56" width="12" height="10" rx="2" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1"/>
|
||||
<text x="178" y="66" fill="#7c3aed" font-size="10" font-weight="600">Protocols</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 (core tool set)</text>
|
||||
<text x="394" y="114" fill="#2563eb" font-size="8">base(5) · task(5) · team(7)</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">Protocol A: Shutdown (Lead initiates → Teammate responds)</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">② Teammate: 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">Protocol B: Plan Approval (Teammate initiates → Lead reviews)</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">plan_request 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">① Teammate: 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">③ Teammate: receives</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 sends the requirement; submit_plan creates the reviewable 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">State Machine (shared by both protocols)</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 Storage</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: find request by 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">Two protocols, one mechanism:</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">and</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">Share the same pending → approved / rejected state machine. New protocol type = new msg_type, no new state machine needed. request_id links request and response.</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">Note:</text>
|
||||
<text x="100" y="588" fill="#475569" font-size="9">request_plan sends plan_request; submit_plan creates a request_id and waits for review.</text>
|
||||
<text x="55" y="602" fill="#475569" font-size="9">submit_plan is the protocol entry point (msg_type="plan_approval_request"), initiated by teammate, carrying request_id into 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">Runtime: MessageBus + persistent teammates + automatic delivery</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">Protocol: request_id + dispatch + pending_requests + plan gate</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,141 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 664" 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="664" 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="14" 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">チームランタイム</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">協調プロトコル</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">base(5) · task(5) · team(7)</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">プロトコル A:shutdown フロー(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">プロトコル B:plan 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">plan_request メッセージ</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">2つのプロトコル、1つのメカニズム:</text>
|
||||
<rect x="270" y="512" width="130" height="18" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
|
||||
<text x="335" y="525" fill="#92400e" font-size="9" text-anchor="middle">shutdown_request</text>
|
||||
<text x="408" y="525" fill="#475569" font-size="10">と</text>
|
||||
<rect x="425" y="512" width="140" height="18" rx="4" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
|
||||
<text x="495" 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 は plan_request を送り、submit_plan は request_id を作ってレビューを待つ。</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">Runtime: MessageBus + 永続チームメイト + 自動イベント配信</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">Protocol: request_id + dispatch + pending_requests + プランゲート</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,141 @@
|
||||
<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">团队运行时</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">协作协议</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">基础工具(5) · task(5) · team(7)</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">协议 A:shutdown 流程(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">协议 B:plan 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">plan_request 消息</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 发送 plan_request;submit_plan 生成 request_id 并等待审批。</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">运行时: MessageBus + 持久队友 + 自动事件投递</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">协议: request_id + dispatch + pending_requests + 计划闸门</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,65 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 296" 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="#0891b2"/>
|
||||
</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-cyan" 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="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" 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="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="720" height="296" fill="#fafbfc" rx="8"/>
|
||||
<rect x="0" y="0" width="720" height="38" fill="url(#header)" rx="8"/>
|
||||
<rect x="0" y="30" width="720" height="8" fill="url(#header)"/>
|
||||
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Team Topology — Lead ↔ MessageBus ↔ Teammates</text>
|
||||
|
||||
<!-- Lead -->
|
||||
<rect x="260" y="58" width="200" height="68" rx="8" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="360" y="82" fill="#0e7490" font-size="13" font-weight="700" text-anchor="middle">Lead Agent</text>
|
||||
<text x="360" y="100" fill="#0e7490" font-size="10" text-anchor="middle">Main loop + spawn + inbox handling</text>
|
||||
<text x="360" y="116" fill="#0e7490" font-size="10" text-anchor="middle">runtime delivers team events automatically</text>
|
||||
|
||||
<!-- Message Bus -->
|
||||
<rect x="80" y="150" width="560" height="26" rx="13" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="360" y="168" fill="#92400e" font-size="11" font-weight="700" text-anchor="middle">Message Bus (.mailboxes/*.jsonl)</text>
|
||||
|
||||
<!-- Teammates -->
|
||||
<rect x="40" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="130" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Alice (Backend)</text>
|
||||
<text x="130" y="254" fill="#166534" font-size="9" text-anchor="middle">own loop → inbox → work → reply</text>
|
||||
|
||||
<rect x="270" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="360" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Bob (Frontend)</text>
|
||||
<text x="360" y="254" fill="#166534" font-size="9" text-anchor="middle">own loop → inbox → work → reply</text>
|
||||
|
||||
<rect x="500" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="590" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Charlie (QA)</text>
|
||||
<text x="590" y="254" fill="#166534" font-size="9" text-anchor="middle">own loop → inbox → work → reply</text>
|
||||
|
||||
<!-- Lead ↔ Bus -->
|
||||
<line x1="330" y1="126" x2="330" y2="150" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="300" y="142" fill="#0891b2" font-size="7">send</text>
|
||||
<line x1="390" y1="150" x2="390" y2="126" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="398" y="142" fill="#0891b2" font-size="7">inbox</text>
|
||||
|
||||
<!-- Bus → Teammates -->
|
||||
<line x1="120" y1="176" x2="120" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="350" y1="176" x2="350" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="176" x2="570" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<text x="82" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="312" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="532" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<line x1="140" y1="214" x2="140" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="370" y1="214" x2="370" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="590" y1="214" x2="590" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="145" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="375" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="595" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,65 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 296" 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="#0891b2"/>
|
||||
</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-cyan" 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="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" 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="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="720" height="296" fill="#fafbfc" rx="8"/>
|
||||
<rect x="0" y="0" width="720" height="38" fill="url(#header)" rx="8"/>
|
||||
<rect x="0" y="30" width="720" height="8" fill="url(#header)"/>
|
||||
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Team Topology — Lead ↔ MessageBus ↔ チームメイト</text>
|
||||
|
||||
<!-- Lead -->
|
||||
<rect x="260" y="58" width="200" height="68" rx="8" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="360" y="82" fill="#0e7490" font-size="13" font-weight="700" text-anchor="middle">Lead Agent</text>
|
||||
<text x="360" y="100" fill="#0e7490" font-size="10" text-anchor="middle">メインループ + spawn + inbox 処理</text>
|
||||
<text x="360" y="116" fill="#0e7490" font-size="10" text-anchor="middle">ランタイムがチームイベントを自動配信</text>
|
||||
|
||||
<!-- Message Bus -->
|
||||
<rect x="80" y="150" width="560" height="26" rx="13" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="360" y="168" fill="#92400e" font-size="11" font-weight="700" text-anchor="middle">Message Bus (.mailboxes/*.jsonl)</text>
|
||||
|
||||
<!-- チームメイト -->
|
||||
<rect x="40" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="130" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Alice (Backend)</text>
|
||||
<text x="130" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 作業 → 返信</text>
|
||||
|
||||
<rect x="270" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="360" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Bob (Frontend)</text>
|
||||
<text x="360" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 作業 → 返信</text>
|
||||
|
||||
<rect x="500" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="590" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Charlie (QA)</text>
|
||||
<text x="590" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 作業 → 返信</text>
|
||||
|
||||
<!-- Lead ↔ Bus -->
|
||||
<line x1="330" y1="126" x2="330" y2="150" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="300" y="142" fill="#0891b2" font-size="7">send</text>
|
||||
<line x1="390" y1="150" x2="390" y2="126" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="398" y="142" fill="#0891b2" font-size="7">inbox</text>
|
||||
|
||||
<!-- Bus → チームメイト -->
|
||||
<line x1="120" y1="176" x2="120" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="350" y1="176" x2="350" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="176" x2="570" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<text x="82" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="312" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="532" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<line x1="140" y1="214" x2="140" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="370" y1="214" x2="370" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="590" y1="214" x2="590" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="145" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="375" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="595" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
72
web/public/course-assets/s13_agent_teams/team-topology.svg
Normal file
@@ -0,0 +1,72 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 296" 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="#0891b2"/>
|
||||
</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-cyan" 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="#0891b2"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber" 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="#d97706"/>
|
||||
</marker>
|
||||
<marker id="arrow-amber-left" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
||||
<path d="M 10 0 L 0 5 L 10 10 z" fill="#d97706"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect width="720" height="296" fill="#fafbfc" rx="8"/>
|
||||
<rect x="0" y="0" width="720" height="38" fill="url(#header)" rx="8"/>
|
||||
<rect x="0" y="30" width="720" height="8" fill="url(#header)"/>
|
||||
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Team Topology — Lead ↔ MessageBus ↔ Teammates</text>
|
||||
|
||||
<!-- Lead: x=260..460, y=58..126 -->
|
||||
<rect x="260" y="58" width="200" height="68" rx="8" fill="#ecfeff" stroke="#0891b2" stroke-width="2"/>
|
||||
<text x="360" y="82" fill="#0e7490" font-size="13" font-weight="700" text-anchor="middle">Lead Agent</text>
|
||||
<text x="360" y="100" fill="#0e7490" font-size="10" text-anchor="middle">主循环 + spawn + inbox 处理</text>
|
||||
<text x="360" y="116" fill="#0e7490" font-size="10" text-anchor="middle">运行时自动投递团队事件</text>
|
||||
|
||||
<!-- Message Bus: x=80..640, y=150..176 (26px tall) -->
|
||||
<rect x="80" y="150" width="560" height="26" rx="13" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
|
||||
<text x="360" y="168" fill="#92400e" font-size="11" font-weight="700" text-anchor="middle">Message Bus (.mailboxes/*.jsonl)</text>
|
||||
|
||||
<!-- Teammates: y=214..274 (60px tall) -->
|
||||
<rect x="40" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="130" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Alice (Backend)</text>
|
||||
<text x="130" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 干活 → 回复</text>
|
||||
|
||||
<rect x="270" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="360" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Bob (Frontend)</text>
|
||||
<text x="360" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 干活 → 回复</text>
|
||||
|
||||
<rect x="500" y="214" width="180" height="60" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
|
||||
<text x="590" y="238" fill="#166534" font-size="12" font-weight="700" text-anchor="middle">Charlie (QA)</text>
|
||||
<text x="590" y="254" fill="#166534" font-size="9" text-anchor="middle">独立 loop → inbox → 干活 → 回复</text>
|
||||
|
||||
<!-- ===== Lead ↔ Bus (gap: 126→150 = 24px) ===== -->
|
||||
<!-- Lead → Bus (send/spawn): x=330 -->
|
||||
<line x1="330" y1="126" x2="330" y2="150" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="300" y="142" fill="#0891b2" font-size="7">send</text>
|
||||
<!-- Bus → Lead (inbox delivery): x=390 -->
|
||||
<line x1="390" y1="150" x2="390" y2="126" stroke="#0891b2" stroke-width="1.5" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="398" y="142" fill="#0891b2" font-size="7">inbox</text>
|
||||
|
||||
<!-- ===== Bus → Teammates (gap: 176→214 = 38px) ===== -->
|
||||
<!-- Incoming (solid): from Bus bottom to Teammate top -->
|
||||
<line x1="120" y1="176" x2="120" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="350" y1="176" x2="350" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="176" x2="570" y2="214" stroke="#555" stroke-width="1" marker-end="url(#arrow)"/>
|
||||
<text x="82" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="312" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<text x="532" y="195" fill="#16a34a" font-size="9" font-weight="600">receive</text>
|
||||
<!-- Outgoing / send_message back (dashed, offset 20px right) -->
|
||||
<line x1="140" y1="214" x2="140" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="370" y1="214" x2="370" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<line x1="590" y1="214" x2="590" y2="176" stroke="#0891b2" stroke-width="1" stroke-dasharray="4,2" marker-end="url(#arrow-cyan)"/>
|
||||
<text x="145" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="375" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
<text x="595" y="203" fill="#0891b2" font-size="9" font-weight="600">send</text>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |