refactor: streamline the course to 17 lessons

This commit is contained in:
Haoran
2026-08-12 03:02:42 +08:00
parent ab35e59672
commit 7e2f2fd99b
250 changed files with 12179 additions and 18653 deletions

View File

@@ -1,110 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 380" font-family="system-ui, -apple-system, sans-serif">
<defs>
<marker id="arrow" 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="#555"/>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto">
<path d="M0 0 L10 5 L0 10 Z" fill="#2563eb"/>
</marker>
<marker id="arrow-blue" 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="#2563eb"/>
</marker>
<marker id="arrow-green" 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="#16a34a"/>
</marker>
<marker id="arrow-amber" 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="#d97706"/>
</marker>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/>
<stop offset="100%" stop-color="#2563eb"/>
</linearGradient>
</defs>
<rect width="800" height="380" rx="8" fill="#fafbfc"/>
<rect width="800" height="48" rx="8" fill="#1e3a5f"/>
<rect y="40" width="800" height="8" fill="#1e3a5f"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — Catalog in system prompt, full content in tool_result</text>
<!-- Background -->
<rect width="800" height="380" fill="#fafbfc" rx="8"/>
<text x="32" y="78" fill="#475569" font-size="11" font-weight="700">Startup</text>
<rect x="32" y="90" width="120" height="54" rx="6" fill="#fff" stroke="#64748b"/>
<text x="92" y="112" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">skills/</text>
<text x="92" y="130" fill="#64748b" font-size="9" text-anchor="middle">*/SKILL.md</text>
<line x1="152" y1="117" x2="195" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="198" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="263" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">SkillLoader.scan</text>
<text x="263" y="130" fill="#64748b" font-size="9" text-anchor="middle">parse frontmatter</text>
<line x1="328" y1="117" x2="371" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="374" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="439" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">Skill catalog</text>
<text x="439" y="130" fill="#64748b" font-size="9" text-anchor="middle">name + description</text>
<line x1="504" y1="117" x2="547" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="550" y="90" width="218" height="54" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="659" y="112" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">system prompt</text>
<text x="659" y="130" fill="#64748b" font-size="9" text-anchor="middle">base instructions + catalog</text>
<!-- Title -->
<rect x="0" y="0" width="800" height="48" fill="url(#header)" rx="8"/>
<rect x="0" y="40" width="800" height="8" fill="url(#header)"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — catalog at startup, content on demand</text>
<text x="32" y="190" fill="#475569" font-size="11" font-weight="700">Runtime</text>
<rect x="32" y="204" width="90" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="77" y="233" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<line x1="122" y1="228" x2="149" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="152" y="204" width="110" height="48" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="207" y="224" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">load_skill</text>
<text x="207" y="240" fill="#64748b" font-size="9" text-anchor="middle">name</text>
<line x1="262" y1="228" x2="289" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="292" y="204" width="100" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="342" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">Registry</text>
<text x="342" y="240" fill="#64748b" font-size="9" text-anchor="middle">lookup by name</text>
<line x1="392" y1="228" x2="419" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="422" y="204" width="110" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="477" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">Full content</text>
<text x="477" y="240" fill="#64748b" font-size="9" text-anchor="middle">SKILL.md</text>
<line x1="532" y1="228" x2="559" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="562" y="204" width="100" height="48" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="612" y="224" fill="#065f46" font-size="10" font-weight="700" text-anchor="middle">tool_result</text>
<text x="612" y="240" fill="#64748b" font-size="9" text-anchor="middle">returned to model</text>
<line x1="662" y1="228" x2="689" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="692" y="204" width="76" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="730" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">messages[]</text>
<text x="730" y="240" fill="#64748b" font-size="9" text-anchor="middle">append</text>
<!-- ===== History preserved ===== -->
<text x="50" y="96" fill="#94a3b8" font-size="11" font-weight="600">History preserved</text>
<!-- messages[] -->
<rect x="40" y="108" width="110" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="95" y="135" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- → LLM -->
<line x1="150" y1="130" x2="198" y2="130" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<!-- LLM -->
<rect x="200" y="106" width="110" height="48" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="128" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">LLM</text>
<text x="255" y="146" fill="#64748b" font-size="9" text-anchor="middle">stop_reason=tool_use?</text>
<!-- No → return -->
<line x1="255" y1="154" x2="255" y2="178" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<text x="268" y="172" fill="#2563eb" font-size="9" font-weight="600">No</text>
<rect x="200" y="180" width="110" height="28" rx="14" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="198" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">Return result</text>
<!-- Yes → PreToolUse -->
<line x1="310" y1="130" x2="348" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<text x="325" y="122" fill="#d97706" font-size="9" font-weight="600">Yes</text>
<!-- PreToolUse (s04) -->
<rect x="350" y="108" width="90" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="395" y="128" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">trigger_hooks</text>
<text x="395" y="142" fill="#64748b" font-size="8" text-anchor="middle">PreToolUse</text>
<!-- → TOOL_HANDLERS -->
<line x1="440" y1="130" x2="488" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="490" y="88" width="120" height="130" rx="10" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="550" y="108" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">TOOL_HANDLERS</text>
<!-- s06 tools -->
<rect x="500" y="116" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="129" fill="#1e3a5f" font-size="8" text-anchor="middle">bash · read · write</text>
<rect x="500" y="138" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="151" fill="#1e3a5f" font-size="8" text-anchor="middle">edit · glob · todo</text>
<rect x="500" y="160" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="173" fill="#1e3a5f" font-size="8" text-anchor="middle">task (subagent)</text>
<rect x="500" y="186" width="100" height="22" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
<text x="550" y="201" fill="#166534" font-size="9" font-weight="700" text-anchor="middle">load_skill</text>
<!-- ===== Loop back ===== -->
<path d="M 550 218 L 550 270 L 95 270 L 95 152" fill="none" stroke="#555" stroke-width="2" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="320" y="290" fill="#64748b" font-size="10" text-anchor="middle">Results appended to messages[], loop continues</text>
<!-- ===== s07 two-level injection labels (right side) ===== -->
<text x="710" y="220" fill="#16a34a" font-size="11" font-weight="700" text-anchor="middle">s07 new</text>
<!-- ① Startup SYSTEM injection -->
<rect x="640" y="86" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="106" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">① build_system()</text>
<text x="710" y="120" fill="#64748b" font-size="8" text-anchor="middle">Scan skills/ first line at startup</text>
<text x="710" y="134" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ inject SYSTEM prompt</text>
<!-- ② Runtime load_skill → tool_result -->
<rect x="640" y="148" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="168" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">② load_skill(name)</text>
<text x="710" y="182" fill="#64748b" font-size="8" text-anchor="middle">Read full SKILL.md at runtime</text>
<text x="710" y="196" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ inject tool_result</text>
<!-- ① → LLM (top connection) -->
<path d="M 710 86 L 710 68 L 255 68 L 255 106" fill="none" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-green)"/>
<text x="480" y="64" fill="#166534" font-size="7" font-weight="600">SYSTEM has skill catalog, carried every turn</text>
<!-- ② → load_skill (short connection) -->
<line x1="640" y1="176" x2="600" y2="197" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3"/>
<!-- ===== Legend ===== -->
<rect x="60" y="308" width="680" height="44" rx="6" fill="#f1f5f9"/>
<rect x="80" y="322" width="12" height="12" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="332" fill="#334155" font-size="10">History preserved (loop, hooks, TODO, subagent — unchanged)</text>
<rect x="80" y="338" width="12" height="12" rx="2" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="100" y="348" fill="#334155" font-size="10">s07 new (startup catalog in SYSTEM + load_skill tool)</text>
<path d="M730 252 V316 H77 V252" fill="none" stroke="#2563eb" stroke-width="2" stroke-dasharray="6 4" marker-end="url(#arrow)"/>
<text x="403" y="309" fill="#475569" font-size="10" text-anchor="middle">The next LLM call receives the updated messages[]</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,110 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 380" font-family="system-ui, -apple-system, sans-serif">
<defs>
<marker id="arrow" 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="#555"/>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto">
<path d="M0 0 L10 5 L0 10 Z" fill="#2563eb"/>
</marker>
<marker id="arrow-blue" 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="#2563eb"/>
</marker>
<marker id="arrow-green" 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="#16a34a"/>
</marker>
<marker id="arrow-amber" 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="#d97706"/>
</marker>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/>
<stop offset="100%" stop-color="#2563eb"/>
</linearGradient>
</defs>
<rect width="800" height="380" rx="8" fill="#fafbfc"/>
<rect width="800" height="48" rx="8" fill="#1e3a5f"/>
<rect y="40" width="800" height="8" fill="#1e3a5f"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — カタログは system prompt、完全な内容は tool_result</text>
<!-- 背景 -->
<rect width="800" height="380" fill="#fafbfc" rx="8"/>
<text x="32" y="78" fill="#475569" font-size="11" font-weight="700">起動時</text>
<rect x="32" y="90" width="120" height="54" rx="6" fill="#fff" stroke="#64748b"/>
<text x="92" y="112" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">skills/</text>
<text x="92" y="130" fill="#64748b" font-size="9" text-anchor="middle">*/SKILL.md</text>
<line x1="152" y1="117" x2="195" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="198" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="263" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">SkillLoader.scan</text>
<text x="263" y="130" fill="#64748b" font-size="9" text-anchor="middle">frontmatter を解析</text>
<line x1="328" y1="117" x2="371" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="374" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="439" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">スキルカタログ</text>
<text x="439" y="130" fill="#64748b" font-size="9" text-anchor="middle">name + description</text>
<line x1="504" y1="117" x2="547" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="550" y="90" width="218" height="54" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="659" y="112" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">system prompt</text>
<text x="659" y="130" fill="#64748b" font-size="9" text-anchor="middle">基本指示 + カタログ</text>
<!-- タイトル -->
<rect x="0" y="0" width="800" height="48" fill="url(#header)" rx="8"/>
<rect x="0" y="40" width="800" height="8" fill="url(#header)"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — 起動時にカタログ注入、実行時にオンデマンド読み込み</text>
<text x="32" y="190" fill="#475569" font-size="11" font-weight="700">実行時</text>
<rect x="32" y="204" width="90" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="77" y="233" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<line x1="122" y1="228" x2="149" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="152" y="204" width="110" height="48" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="207" y="224" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">load_skill</text>
<text x="207" y="240" fill="#64748b" font-size="9" text-anchor="middle">name</text>
<line x1="262" y1="228" x2="289" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="292" y="204" width="100" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="342" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">レジストリ</text>
<text x="342" y="240" fill="#64748b" font-size="9" text-anchor="middle">名前で検索</text>
<line x1="392" y1="228" x2="419" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="422" y="204" width="110" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="477" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">完全な内容</text>
<text x="477" y="240" fill="#64748b" font-size="9" text-anchor="middle">SKILL.md</text>
<line x1="532" y1="228" x2="559" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="562" y="204" width="100" height="48" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="612" y="224" fill="#065f46" font-size="10" font-weight="700" text-anchor="middle">tool_result</text>
<text x="612" y="240" fill="#64748b" font-size="9" text-anchor="middle">モデルへ返す</text>
<line x1="662" y1="228" x2="689" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="692" y="204" width="76" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="730" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">messages[]</text>
<text x="730" y="240" fill="#64748b" font-size="9" text-anchor="middle">追加</text>
<!-- ===== 過去章を保持 ===== -->
<text x="50" y="96" fill="#94a3b8" font-size="11" font-weight="600">過去章を保持</text>
<!-- messages[] -->
<rect x="40" y="108" width="110" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="95" y="135" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- → LLM -->
<line x1="150" y1="130" x2="198" y2="130" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<!-- LLM -->
<rect x="200" y="106" width="110" height="48" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="128" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">LLM</text>
<text x="255" y="146" fill="#64748b" font-size="9" text-anchor="middle">stop_reason=tool_use?</text>
<!-- No → 戻る -->
<line x1="255" y1="154" x2="255" y2="178" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<text x="268" y="172" fill="#2563eb" font-size="9" font-weight="600">No</text>
<rect x="200" y="180" width="110" height="28" rx="14" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="198" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">結果を返す</text>
<!-- Yes → PreToolUse -->
<line x1="310" y1="130" x2="348" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<text x="325" y="122" fill="#d97706" font-size="9" font-weight="600">Yes</text>
<!-- PreToolUse (s04) -->
<rect x="350" y="108" width="90" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="395" y="128" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">trigger_hooks</text>
<text x="395" y="142" fill="#64748b" font-size="8" text-anchor="middle">PreToolUse</text>
<!-- → TOOL_HANDLERS -->
<line x1="440" y1="130" x2="488" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="490" y="88" width="120" height="130" rx="10" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="550" y="108" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">TOOL_HANDLERS</text>
<!-- s06 ツール -->
<rect x="500" y="116" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="129" fill="#1e3a5f" font-size="8" text-anchor="middle">bash · read · write</text>
<rect x="500" y="138" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="151" fill="#1e3a5f" font-size="8" text-anchor="middle">edit · glob · todo</text>
<rect x="500" y="160" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="173" fill="#1e3a5f" font-size="8" text-anchor="middle">task (subagent)</text>
<rect x="500" y="186" width="100" height="22" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
<text x="550" y="201" fill="#166534" font-size="9" font-weight="700" text-anchor="middle">load_skill</text>
<!-- ===== ループバック ===== -->
<path d="M 550 218 L 550 270 L 95 270 L 95 152" fill="none" stroke="#555" stroke-width="2" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="320" y="290" fill="#64748b" font-size="10" text-anchor="middle">結果を messages[] に追加、ループ継続</text>
<!-- ===== s07 2 層注入ラベル(右側) ===== -->
<text x="710" y="220" fill="#16a34a" font-size="11" font-weight="700" text-anchor="middle">s07 新規</text>
<!-- ① 起動時 SYSTEM 注入 -->
<rect x="640" y="86" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="106" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">① build_system()</text>
<text x="710" y="120" fill="#64748b" font-size="8" text-anchor="middle">起動時に skills/ の 1 行目をスキャン</text>
<text x="710" y="134" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ SYSTEM プロンプトに注入</text>
<!-- ② 実行時 load_skill → tool_result -->
<rect x="640" y="148" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="168" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">② load_skill(name)</text>
<text x="710" y="182" fill="#64748b" font-size="8" text-anchor="middle">実行時に完全な SKILL.md を読み取り</text>
<text x="710" y="196" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ tool_result に注入</text>
<!-- ① → LLM上部接続 -->
<path d="M 710 86 L 710 68 L 255 68 L 255 106" fill="none" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-green)"/>
<text x="480" y="64" fill="#166534" font-size="7" font-weight="600">SYSTEM にスキルカタログ、毎ターン携帯</text>
<!-- ② → load_skill短接続 -->
<line x1="640" y1="176" x2="600" y2="197" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3"/>
<!-- ===== 凡例 ===== -->
<rect x="60" y="308" width="680" height="44" rx="6" fill="#f1f5f9"/>
<rect x="80" y="322" width="12" height="12" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="332" fill="#334155" font-size="10">過去章を保持ループ、フック、TODO、サブ Agent — 変更なし)</text>
<rect x="80" y="338" width="12" height="12" rx="2" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="100" y="348" fill="#334155" font-size="10">s07 新規(起動時カタログ注入 SYSTEM + load_skill ツール)</text>
<path d="M730 252 V316 H77 V252" fill="none" stroke="#2563eb" stroke-width="2" stroke-dasharray="6 4" marker-end="url(#arrow)"/>
<text x="403" y="309" fill="#475569" font-size="10" text-anchor="middle">次の LLM 呼び出しは更新後の messages[] を受け取る</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,110 +1,55 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 380" font-family="system-ui, -apple-system, sans-serif">
<defs>
<marker id="arrow" 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="#555"/>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto">
<path d="M0 0 L10 5 L0 10 Z" fill="#2563eb"/>
</marker>
<marker id="arrow-blue" 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="#2563eb"/>
</marker>
<marker id="arrow-green" 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="#16a34a"/>
</marker>
<marker id="arrow-amber" 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="#d97706"/>
</marker>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/>
<stop offset="100%" stop-color="#2563eb"/>
</linearGradient>
</defs>
<rect width="800" height="380" rx="8" fill="#fafbfc"/>
<rect width="800" height="48" rx="8" fill="#1e3a5f"/>
<rect y="40" width="800" height="8" fill="#1e3a5f"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — 目录进入 system prompt完整内容进入 tool_result</text>
<!-- 背景 -->
<rect width="800" height="380" fill="#fafbfc" rx="8"/>
<text x="32" y="78" fill="#475569" font-size="11" font-weight="700">启动时</text>
<rect x="32" y="90" width="120" height="54" rx="6" fill="#fff" stroke="#64748b"/>
<text x="92" y="112" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">skills/</text>
<text x="92" y="130" fill="#64748b" font-size="9" text-anchor="middle">*/SKILL.md</text>
<line x1="152" y1="117" x2="195" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="198" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="263" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">SkillLoader.scan</text>
<text x="263" y="130" fill="#64748b" font-size="9" text-anchor="middle">解析 frontmatter</text>
<line x1="328" y1="117" x2="371" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="374" y="90" width="130" height="54" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="439" y="112" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">技能目录</text>
<text x="439" y="130" fill="#64748b" font-size="9" text-anchor="middle">name + description</text>
<line x1="504" y1="117" x2="547" y2="117" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="550" y="90" width="218" height="54" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="659" y="112" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">system prompt</text>
<text x="659" y="130" fill="#64748b" font-size="9" text-anchor="middle">基础指令 + 技能目录</text>
<!-- 标题 -->
<rect x="0" y="0" width="800" height="48" fill="url(#header)" rx="8"/>
<rect x="0" y="40" width="800" height="8" fill="url(#header)"/>
<text x="400" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Skill Loading — 启动时注入目录,运行时按需加载内容</text>
<text x="32" y="190" fill="#475569" font-size="11" font-weight="700">运行时</text>
<rect x="32" y="204" width="90" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="77" y="233" fill="#1e293b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<line x1="122" y1="228" x2="149" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="152" y="204" width="110" height="48" rx="6" fill="#eff6ff" stroke="#2563eb"/>
<text x="207" y="224" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">load_skill</text>
<text x="207" y="240" fill="#64748b" font-size="9" text-anchor="middle">name</text>
<line x1="262" y1="228" x2="289" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="292" y="204" width="100" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="342" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">注册表查询</text>
<text x="342" y="240" fill="#64748b" font-size="9" text-anchor="middle">按名称</text>
<line x1="392" y1="228" x2="419" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="422" y="204" width="110" height="48" rx="6" fill="#fff" stroke="#64748b"/>
<text x="477" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">完整内容</text>
<text x="477" y="240" fill="#64748b" font-size="9" text-anchor="middle">SKILL.md</text>
<line x1="532" y1="228" x2="559" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="562" y="204" width="100" height="48" rx="6" fill="#ecfdf5" stroke="#059669"/>
<text x="612" y="224" fill="#065f46" font-size="10" font-weight="700" text-anchor="middle">tool_result</text>
<text x="612" y="240" fill="#64748b" font-size="9" text-anchor="middle">返回模型</text>
<line x1="662" y1="228" x2="689" y2="228" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="692" y="204" width="76" height="48" rx="6" fill="#fff" stroke="#2563eb"/>
<text x="730" y="224" fill="#1e293b" font-size="10" font-weight="700" text-anchor="middle">messages[]</text>
<text x="730" y="240" fill="#64748b" font-size="9" text-anchor="middle">追加</text>
<!-- ===== 历史章节保留 ===== -->
<text x="50" y="96" fill="#94a3b8" font-size="11" font-weight="600">历史章节保留</text>
<!-- messages[] -->
<rect x="40" y="108" width="110" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="95" y="135" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- → LLM -->
<line x1="150" y1="130" x2="198" y2="130" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<!-- LLM -->
<rect x="200" y="106" width="110" height="48" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="128" fill="#1e3a5f" font-size="13" font-weight="700" text-anchor="middle">LLM</text>
<text x="255" y="146" fill="#64748b" font-size="9" text-anchor="middle">stop_reason=tool_use?</text>
<!-- 否 → 返回 -->
<line x1="255" y1="154" x2="255" y2="178" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow-blue)"/>
<text x="268" y="172" fill="#2563eb" font-size="9" font-weight="600"></text>
<rect x="200" y="180" width="110" height="28" rx="14" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="255" y="198" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">返回结果</text>
<!-- 是 → PreToolUse -->
<line x1="310" y1="130" x2="348" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<text x="325" y="122" fill="#d97706" font-size="9" font-weight="600"></text>
<!-- PreToolUse (s04) -->
<rect x="350" y="108" width="90" height="44" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="395" y="128" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">trigger_hooks</text>
<text x="395" y="142" fill="#64748b" font-size="8" text-anchor="middle">PreToolUse</text>
<!-- → TOOL_HANDLERS -->
<line x1="440" y1="130" x2="488" y2="130" stroke="#555" stroke-width="2" marker-end="url(#arrow)"/>
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="490" y="88" width="120" height="130" rx="10" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="550" y="108" fill="#1e3a5f" font-size="10" font-weight="700" text-anchor="middle">TOOL_HANDLERS</text>
<!-- s06 工具 -->
<rect x="500" y="116" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="129" fill="#1e3a5f" font-size="8" text-anchor="middle">bash · read · write</text>
<rect x="500" y="138" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="151" fill="#1e3a5f" font-size="8" text-anchor="middle">edit · glob · todo</text>
<rect x="500" y="160" width="100" height="18" rx="3" fill="#fff" stroke="#2563eb" stroke-width="0.8"/>
<text x="550" y="173" fill="#1e3a5f" font-size="8" text-anchor="middle">task (subagent)</text>
<rect x="500" y="186" width="100" height="22" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
<text x="550" y="201" fill="#166534" font-size="9" font-weight="700" text-anchor="middle">load_skill</text>
<!-- ===== 回环 ===== -->
<path d="M 550 218 L 550 270 L 95 270 L 95 152" fill="none" stroke="#555" stroke-width="2" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="320" y="290" fill="#64748b" font-size="10" text-anchor="middle">结果追加到 messages[],循环继续</text>
<!-- ===== s07 两级注入标注(右侧) ===== -->
<text x="710" y="220" fill="#16a34a" font-size="11" font-weight="700" text-anchor="middle">s07 新增</text>
<!-- ① 启动时注入 SYSTEM -->
<rect x="640" y="86" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="106" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">① build_system()</text>
<text x="710" y="120" fill="#64748b" font-size="8" text-anchor="middle">启动时扫描 skills/ 第一行</text>
<text x="710" y="134" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ 注入 SYSTEM prompt</text>
<!-- ② 运行时 load_skill → tool_result -->
<rect x="640" y="148" width="140" height="56" rx="8" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.5"/>
<text x="710" y="168" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">② load_skill(name)</text>
<text x="710" y="182" fill="#64748b" font-size="8" text-anchor="middle">运行时读完整 SKILL.md</text>
<text x="710" y="196" fill="#166534" font-size="8" font-weight="600" text-anchor="middle">→ 注入 tool_result</text>
<!-- ① → LLM顶部连线 -->
<path d="M 710 86 L 710 68 L 255 68 L 255 106" fill="none" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-green)"/>
<text x="480" y="64" fill="#166534" font-size="7" font-weight="600">SYSTEM 含技能目录,每轮都带</text>
<!-- ② → load_skill短连接线 -->
<line x1="640" y1="176" x2="600" y2="197" stroke="#16a34a" stroke-width="1.5" stroke-dasharray="4,3"/>
<!-- ===== 图例 ===== -->
<rect x="60" y="308" width="680" height="44" rx="6" fill="#f1f5f9"/>
<rect x="80" y="322" width="12" height="12" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="332" fill="#334155" font-size="10">历史章节保留循环、钩子、TODO、subagent — 完全不变)</text>
<rect x="80" y="338" width="12" height="12" rx="2" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="100" y="348" fill="#334155" font-size="10">s07 新增(启动时目录注入 SYSTEM + load_skill 工具)</text>
<path d="M730 252 V316 H77 V252" fill="none" stroke="#2563eb" stroke-width="2" stroke-dasharray="6 4" marker-end="url(#arrow)"/>
<text x="403" y="309" fill="#475569" font-size="10" text-anchor="middle">下一次 LLM 调用继续使用更新后的 messages[]</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -16,22 +16,22 @@
<!-- Trigger Condition -->
<rect x="20" y="54" width="680" height="44" rx="6" fill="#fef2f2" stroke="#fca5a5" stroke-width="1"/>
<text x="35" y="70" fill="#991b1b" font-size="11" font-weight="600">Trigger Condition</text>
<text x="140" y="70" fill="#991b1b" font-size="11">After Steps 13, estimate_size(messages) &gt; CONTEXT_LIMIT.</text>
<text x="140" y="86" fill="#991b1b" font-size="10">The current CONTEXT_LIMIT is 50,000 characters.</text>
<text x="140" y="70" fill="#991b1b" font-size="11">After Steps 13, estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT.</text>
<text x="140" y="86" fill="#991b1b" font-size="10">The current CONTEXT_CHAR_LIMIT is 50,000 characters.</text>
<!-- Steps -->
<rect x="20" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="120" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">Step 1: Save transcript</text>
<text x="40" y="152" fill="#475569" font-size="10">Write conversation to .transcripts/</text>
<text x="40" y="168" fill="#475569" font-size="10">One JSONL message per line</text>
<text x="40" y="184" fill="#475569" font-size="10">File: transcript_{time}.jsonl</text>
<text x="40" y="184" fill="#475569" font-size="10">File: transcript_{uuid}.jsonl</text>
<text x="40" y="200" fill="#94a3b8" font-size="9">Full transcript stays on disk</text>
<line x1="225" y1="161" x2="265" y2="161" stroke="#dc2626" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="270" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="370" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">Step 2: Factual summary</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">Conversation is untrusted data</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">Conversation is data to summarize</text>
<text x="290" y="166" fill="#475569" font-size="9">Summary preserves 5 categories:</text>
<text x="370" y="180" fill="#94a3b8" font-size="8" text-anchor="middle">goal · findings and decisions · files</text>
<text x="370" y="192" fill="#94a3b8" font-size="8" text-anchor="middle">remaining work · user constraints</text>
@@ -42,7 +42,7 @@
<rect x="520" y="106" width="180" height="110" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="2"/>
<text x="610" y="130" fill="#991b1b" font-size="12" font-weight="700" text-anchor="middle">Step 3: Replace history</text>
<text x="610" y="152" fill="#991b1b" font-size="9" text-anchor="middle">Old history → 1 message</text>
<text x="610" y="168" fill="#991b1b" font-size="9" text-anchor="middle">Request + reference state</text>
<text x="610" y="168" fill="#991b1b" font-size="9" text-anchor="middle">Request + conversation summary</text>
<text x="610" y="184" fill="#991b1b" font-size="9" text-anchor="middle">System separates instructions/data</text>
<text x="610" y="200" fill="#ef4444" font-size="9" text-anchor="middle">Transcript remains on disk</text>
@@ -61,8 +61,8 @@
<rect x="380" y="234" width="320" height="94" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="540" y="256" fill="#991b1b" font-size="11" font-weight="600" text-anchor="middle">After messages</text>
<rect x="395" y="264" width="290" height="32" rx="4" fill="#fee2e2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">Authoritative request: captured at input</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">Reference state: untrusted factual summary</text>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">Current user request: captured at input</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">Conversation summary: facts and remaining work</text>
<text x="540" y="318" fill="#94a3b8" font-size="9" text-anchor="middle">One summary message, well below the limit</text>
<!-- Error recovery -->

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -16,22 +16,22 @@
<!-- トリガー条件 -->
<rect x="20" y="54" width="680" height="44" rx="6" fill="#fef2f2" stroke="#fca5a5" stroke-width="1"/>
<text x="35" y="70" fill="#991b1b" font-size="11" font-weight="600">トリガー条件</text>
<text x="115" y="70" fill="#991b1b" font-size="11">Step 13 の後、estimate_size(messages) &gt; CONTEXT_LIMIT。</text>
<text x="115" y="86" fill="#991b1b" font-size="10">現在の CONTEXT_LIMIT は 50,000 文字。</text>
<text x="115" y="70" fill="#991b1b" font-size="11">Step 13 の後、estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT。</text>
<text x="115" y="86" fill="#991b1b" font-size="10">現在の CONTEXT_CHAR_LIMIT は 50,000 文字。</text>
<!-- ステップ -->
<rect x="20" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="120" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">ステップ 1transcript 保存</text>
<text x="40" y="152" fill="#475569" font-size="10">完全な対話を .transcripts/ に書き込み</text>
<text x="40" y="168" fill="#475569" font-size="10">JSONL 形式、1 行 1 メッセージ</text>
<text x="40" y="184" fill="#475569" font-size="10">transcript_{time}.jsonl</text>
<text x="40" y="184" fill="#475569" font-size="10">transcript_{uuid}.jsonl</text>
<text x="40" y="200" fill="#94a3b8" font-size="9">内容はディスクに残る</text>
<line x1="225" y1="161" x2="265" y2="161" stroke="#dc2626" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="270" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="370" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">ステップ 2事実要約</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">元の対話は信頼しないデータ</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">元の対話は要約対象のデータ</text>
<text x="290" y="166" fill="#475569" font-size="9">要約は 5 種類の情報を保持:</text>
<text x="290" y="180" fill="#94a3b8" font-size="8">目標・発見と判断・関連ファイル</text>
<text x="290" y="192" fill="#94a3b8" font-size="8">残作業・ユーザー制約</text>
@@ -61,8 +61,8 @@
<rect x="380" y="234" width="320" height="94" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="540" y="256" fill="#991b1b" font-size="11" font-weight="600" text-anchor="middle">圧縮後 messages</text>
<rect x="395" y="264" width="290" height="32" rx="4" fill="#fee2e2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">Authoritative request:入力時に取得した要求</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">Reference state信頼しない事実要約</text>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">現在のユーザー要求:入力時に取得</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">対話要約:事実・判断・残作業</text>
<text x="540" y="318" fill="#94a3b8" font-size="9" text-anchor="middle">1 件の要約メッセージ、上限を下回る</text>
<!-- エラー回復 -->

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -16,22 +16,22 @@
<!-- 触发条件 -->
<rect x="20" y="54" width="680" height="44" rx="6" fill="#fef2f2" stroke="#fca5a5" stroke-width="1"/>
<text x="35" y="70" fill="#991b1b" font-size="11" font-weight="600">触发条件</text>
<text x="105" y="70" fill="#991b1b" font-size="11">前三步执行后estimate_size(messages) &gt; CONTEXT_LIMIT。</text>
<text x="105" y="86" fill="#991b1b" font-size="10">当前实现的 CONTEXT_LIMIT 为 50,000 个字符。</text>
<text x="105" y="70" fill="#991b1b" font-size="11">前三步执行后estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT。</text>
<text x="105" y="86" fill="#991b1b" font-size="10">当前实现的 CONTEXT_CHAR_LIMIT 为 50,000 个字符。</text>
<!-- 步骤 -->
<rect x="20" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="120" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">步骤 1保存 transcript</text>
<text x="40" y="152" fill="#475569" font-size="10">完整对话写入 .transcripts/</text>
<text x="40" y="168" fill="#475569" font-size="10">JSONL 格式,一行一条消息</text>
<text x="40" y="184" fill="#475569" font-size="10">文件名transcript_{time}.jsonl</text>
<text x="40" y="184" fill="#475569" font-size="10">文件名transcript_{uuid}.jsonl</text>
<text x="40" y="200" fill="#94a3b8" font-size="9">信息没有丢失,只是移出活跃区</text>
<line x1="225" y1="161" x2="265" y2="161" stroke="#dc2626" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="270" y="106" width="200" height="110" rx="8" fill="#fff" stroke="#94a3b8" stroke-width="1.5"/>
<text x="370" y="130" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">步骤 2生成事实摘要</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">原对话是不可信数据</text>
<text x="370" y="152" fill="#475569" font-size="9" text-anchor="middle">原对话作为待摘要数据</text>
<text x="290" y="166" fill="#475569" font-size="9">摘要保留 5 类信息:</text>
<text x="290" y="180" fill="#94a3b8" font-size="8">目标·发现与决定·相关文件</text>
<text x="290" y="192" fill="#94a3b8" font-size="8">剩余工作·用户约束</text>
@@ -61,8 +61,8 @@
<rect x="380" y="234" width="320" height="94" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="540" y="256" fill="#991b1b" font-size="11" font-weight="600" text-anchor="middle">压缩后 messages</text>
<rect x="395" y="264" width="290" height="32" rx="4" fill="#fee2e2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">Authoritative request:入口捕获的用户要求</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">Reference state不可信的事实摘要</text>
<text x="540" y="276" fill="#991b1b" font-size="9" text-anchor="middle">当前用户要求:入口捕获</text>
<text x="540" y="290" fill="#991b1b" font-size="9" text-anchor="middle">对话摘要:事实、决定与剩余工作</text>
<text x="540" y="318" fill="#94a3b8" font-size="9" text-anchor="middle">1 条摘要消息,显著低于阈值</text>
<!-- 错误后补救 -->

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -30,13 +30,13 @@
<text x="410" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Context Compact: Compression Before LLM Calls, Three Triggers</text>
<!-- Labels -->
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">s07 Preserved</text>
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">Shared Kernel</text>
<text x="180" y="74" fill="#d97706" font-size="11" font-weight="600">s08 New</text>
<!-- ===== ① messages[] ===== -->
<rect x="40" y="132" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="90" y="155" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(s07 preserved)</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(shared)</text>
<!-- messages → pipeline entry -->
<line x1="140" y1="158" x2="168" y2="158" stroke="#d97706" stroke-width="2" marker-end="url(#arrow-amber)"/>
@@ -101,7 +101,7 @@
<rect x="580" y="126" width="130" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="645" y="150" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="645" y="166" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">task · load_skill · ...</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">edit · glob · compact</text>
<!-- LLM API error → emergency compact → retry next turn -->
<path d="M 535 184 L 570 216 L 580 228" fill="none" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-red)"/>
@@ -123,7 +123,7 @@
<rect x="50" y="390" width="720" height="116" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="70" y="404" width="16" height="12" rx="3" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="94" y="414" fill="#334155" font-size="10">s07 Preserved: loop, hooks, skill loading, sub-agents</text>
<text x="94" y="414" fill="#334155" font-size="10">Shared: loop, hooks, permissions, five base tools</text>
<rect x="70" y="426" width="16" height="12" rx="3" fill="#fde68a" stroke="#d97706" stroke-width="1"/>
<text x="94" y="436" fill="#334155" font-size="10">① Every Turn: Steps 1→2→3 run before each LLM call, 0 API</text>

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -30,13 +30,13 @@
<text x="410" y="31" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Context CompactLLM 呼び出し前の圧縮と 3 つのトリガー</text>
<!-- ラベル -->
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">s07 保持</text>
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">共通カーネル</text>
<text x="180" y="74" fill="#d97706" font-size="11" font-weight="600">s08 新規</text>
<!-- ===== ① messages[] ===== -->
<rect x="40" y="132" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="90" y="155" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(s07 保持)</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(共通部分)</text>
<!-- messages → パイプライン入口 -->
<line x1="140" y1="158" x2="168" y2="158" stroke="#d97706" stroke-width="2" marker-end="url(#arrow-amber)"/>
@@ -101,7 +101,7 @@
<rect x="580" y="126" width="130" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="645" y="150" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="645" y="166" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">task · load_skill · ...</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">edit · glob · compact</text>
<!-- LLM API 例外 → 緊急圧縮 → 次ターンで再試行 -->
<path d="M 535 184 L 570 216 L 580 228" fill="none" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-red)"/>
@@ -123,7 +123,7 @@
<rect x="50" y="390" width="720" height="116" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="70" y="404" width="16" height="12" rx="3" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="94" y="414" fill="#334155" font-size="10">s07 保持:ループ、フック、スキルロード、サブエージェント</text>
<text x="94" y="414" fill="#334155" font-size="10">共通:ループ、フック、権限確認、5 個の基本ツール</text>
<rect x="70" y="426" width="16" height="12" rx="3" fill="#fde68a" stroke="#d97706" stroke-width="1"/>
<text x="94" y="436" fill="#334155" font-size="10">① 毎ターンStep 1→2→3 を各 LLM 呼び出し前に実行、0 API</text>

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -30,13 +30,13 @@
<text x="410" y="31" fill="#fff" font-size="16" font-weight="700" text-anchor="middle">Context CompactLLM 调用前压缩,三种触发方式</text>
<!-- 标签 -->
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">s07 保留</text>
<text x="50" y="74" fill="#94a3b8" font-size="11" font-weight="600">共同骨架</text>
<text x="180" y="74" fill="#d97706" font-size="11" font-weight="600">s08 新增</text>
<!-- ===== ① messages[] ===== -->
<rect x="40" y="132" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="90" y="155" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(s07 保留)</text>
<text x="90" y="172" fill="#64748b" font-size="9" text-anchor="middle">(共同部分)</text>
<!-- messages → 管线入口 -->
<line x1="140" y1="158" x2="168" y2="158" stroke="#d97706" stroke-width="2" marker-end="url(#arrow-amber)"/>
@@ -101,7 +101,7 @@
<rect x="580" y="126" width="130" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="645" y="150" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="645" y="166" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">task · load_skill · ...</text>
<text x="645" y="180" fill="#64748b" font-size="9" text-anchor="middle">edit · glob · compact</text>
<!-- LLM API 异常 → 应急压缩 → 下一轮重试 -->
<path d="M 535 184 L 570 216 L 580 228" fill="none" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrow-red)"/>
@@ -123,7 +123,7 @@
<rect x="50" y="390" width="720" height="116" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="70" y="404" width="16" height="12" rx="3" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="94" y="414" fill="#334155" font-size="10">s07 保留循环、hook、技能加载、子 Agent</text>
<text x="94" y="414" fill="#334155" font-size="10">共同骨架循环、hook、权限检查、5 个基础工具</text>
<rect x="70" y="426" width="16" height="12" rx="3" fill="#fde68a" stroke="#d97706" stroke-width="1"/>
<text x="94" y="436" fill="#334155" font-size="10">① 每轮自动Step 1→2→3 在每次 LLM 调用前执行0 API</text>

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -81,7 +81,7 @@
<text x="155" y="412" fill="#991b1b" font-size="13" font-weight="700">compact_history</text>
<text x="305" y="412" fill="#991b1b" font-size="11">size above 50,000 → LLM summary</text>
<text x="650" y="412" fill="#991b1b" font-size="10" text-anchor="end">1 API call</text>
<text x="155" y="428" fill="#dc2626" font-size="9">Condition: estimate_size(messages) &gt; CONTEXT_LIMIT</text>
<text x="155" y="428" fill="#dc2626" font-size="9">Condition: estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT</text>
<text x="155" y="442" fill="#dc2626" font-size="9">Save a transcript, then replace active history with one summary</text>
<!-- ===== Emergency fallback title ===== -->

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -81,7 +81,7 @@
<text x="155" y="412" fill="#991b1b" font-size="13" font-weight="700">compact_history</text>
<text x="305" y="412" fill="#991b1b" font-size="11">サイズが 50,000 超 → LLM 要約</text>
<text x="590" y="412" fill="#991b1b" font-size="10" text-anchor="end">1 API 呼び出し</text>
<text x="155" y="428" fill="#dc2626" font-size="9">条件estimate_size(messages) &gt; CONTEXT_LIMIT</text>
<text x="155" y="428" fill="#dc2626" font-size="9">条件estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT</text>
<text x="155" y="442" fill="#dc2626" font-size="9">transcript 保存後、現在の履歴を 1 件の要約に置換</text>
<!-- ===== 緊急フォールバックタイトル ===== -->

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -81,7 +81,7 @@
<text x="155" y="412" fill="#991b1b" font-size="13" font-weight="700">compact_history</text>
<text x="305" y="412" fill="#991b1b" font-size="11">size 超过 50,000 → LLM 摘要</text>
<text x="590" y="412" fill="#991b1b" font-size="10" text-anchor="end">1 API 调用</text>
<text x="155" y="428" fill="#dc2626" font-size="9">条件estimate_size(messages) &gt; CONTEXT_LIMIT</text>
<text x="155" y="428" fill="#dc2626" font-size="9">条件estimate_chars(messages) &gt; CONTEXT_CHAR_LIMIT</text>
<text x="155" y="442" fill="#dc2626" font-size="9">先保存 transcript再用一条摘要替换当前历史</text>
<!-- ===== 应急兜底标题 ===== -->

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -39,11 +39,11 @@
<text x="535" y="114" fill="#ca8a04" font-size="12" font-weight="600" text-anchor="middle">After (keep only latest 3 complete)</text>
<rect x="390" y="122" width="310" height="95" rx="6" fill="#fefce8" stroke="#ca8a04" stroke-width="1"/>
<rect x="400" y="130" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result saved at .task_outputs/...]</text>
<rect x="400" y="145" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="160" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="175" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="183" fill="#92400e" font-size="8" font-family="monospace">Read file J: (full content, 2800 chars)</text>
<text x="545" y="212" fill="#ca8a04" font-size="9" font-weight="600" text-anchor="middle">Keep latest 3; first 7 become placeholders</text>
@@ -53,6 +53,6 @@
<text x="35" y="248" fill="#1e3a5f" font-size="11" font-weight="600">Rule</text>
<text x="75" y="248" fill="#475569" font-size="10">Keep the latest 3; replace older results above 120 characters with placeholders.</text>
<text x="35" y="264" fill="#1e3a5f" font-size="11" font-weight="600">Placeholder</text>
<text x="105" y="264" fill="#475569" font-size="10">Explain that the result was compacted and that the tool can be run again if needed.</text>
<text x="105" y="264" fill="#475569" font-size="10">Keep the saved path when one exists; otherwise mark the result omitted.</text>
<text x="105" y="280" fill="#94a3b8" font-size="9">The message structure remains valid for the next loop iteration.</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -39,11 +39,11 @@
<text x="535" y="114" fill="#ca8a04" font-size="12" font-weight="600" text-anchor="middle">圧縮後(最新 3 件のみ完全保持)</text>
<rect x="390" y="122" width="310" height="95" rx="6" fill="#fefce8" stroke="#ca8a04" stroke-width="1"/>
<rect x="400" y="130" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result saved at .task_outputs/...]</text>
<rect x="400" y="145" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="160" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="175" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="183" fill="#92400e" font-size="8" font-family="monospace">Read file J: (完全な内容, 2800 文字)</text>
<text x="545" y="212" fill="#ca8a04" font-size="9" font-weight="600" text-anchor="middle">最新 3 件を保持、前 7 件は置換</text>
@@ -53,6 +53,6 @@
<text x="35" y="248" fill="#1e3a5f" font-size="11" font-weight="600">処理規則</text>
<text x="95" y="248" fill="#475569" font-size="10">最新 3 件を保持し、120 文字超の古い結果をプレースホルダーに置換。</text>
<text x="35" y="264" fill="#1e3a5f" font-size="11" font-weight="600">プレースホルダー</text>
<text x="125" y="264" fill="#475569" font-size="10">結果が圧縮済みで、必要ならツールを再実行できることを示す。</text>
<text x="125" y="264" fill="#475569" font-size="10">保存先があればパスを残し、なければ省略済みと示す。</text>
<text x="125" y="280" fill="#94a3b8" font-size="9">メッセージ構造を保ったまま次のループへ進める。</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -38,11 +38,11 @@
<text x="535" y="114" fill="#ca8a04" font-size="12" font-weight="600" text-anchor="middle">压缩后(只保留最近 3 条完整)</text>
<rect x="390" y="122" width="310" height="95" rx="6" fill="#fefce8" stroke="#ca8a04" stroke-width="1"/>
<rect x="400" y="130" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="138" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result saved at .task_outputs/...]</text>
<rect x="400" y="145" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="153" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="160" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result compacted. Re-run if needed.]</text>
<text x="408" y="168" fill="#92400e" font-size="8" font-family="monospace">[Earlier tool result omitted.]</text>
<rect x="400" y="175" width="290" height="10" rx="2" fill="#fef3c7"/>
<text x="408" y="183" fill="#92400e" font-size="8" font-family="monospace">Read file J: (完整内容, 2800 字符)</text>
<text x="545" y="212" fill="#ca8a04" font-size="9" font-weight="600">只保留最近 3 条,前 7 条变占位</text>
@@ -52,6 +52,6 @@
<text x="35" y="248" fill="#1e3a5f" font-size="11" font-weight="600">处理规则</text>
<text x="95" y="248" fill="#475569" font-size="10">最近 3 条保持完整,更早且超过 120 字符的结果替换为占位符。</text>
<text x="35" y="264" fill="#1e3a5f" font-size="11" font-weight="600">占位内容</text>
<text x="95" y="264" fill="#475569" font-size="10">说明原结果已压缩,并提示需要时重新运行对应工具</text>
<text x="95" y="264" fill="#475569" font-size="10">有落盘路径时保留路径,否则标记该结果已省略</text>
<text x="95" y="280" fill="#94a3b8" font-size="9">消息结构保持不变,后续循环仍可继续处理。</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -19,42 +19,42 @@
<!-- Title -->
<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">Memory — Memory loading, extraction, and consolidation on s08 compression pipeline</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Memory — Store, Recall, Extract &amp; Consolidate</text>
<!-- Legend -->
<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">s08 preserved</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">Agent Loop</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="178" y="66" fill="#7c3aed" font-size="10" font-weight="600">s09 new</text>
<text x="178" y="66" fill="#7c3aed" font-size="10" font-weight="600">Memory</text>
<!-- ===== messages[] ===== -->
<rect x="30" y="96" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="126" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- arrow → compression -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- arrow to selection -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Compression pipeline (s08) ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="222" y="108" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">Compression</text>
<text x="222" y="124" fill="#64748b" font-size="9" text-anchor="middle">budget → snip → micro</text>
<text x="222" y="138" fill="#64748b" font-size="9" text-anchor="middle">→ compact_history</text>
<text x="222" y="152" fill="#94a3b8" font-size="8" text-anchor="middle">(s08)</text>
<!-- ===== Selection ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="222" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Selection</text>
<text x="222" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">catalog + current request</text>
<text x="222" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">model or keyword match</text>
<text x="222" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">up to 5 records</text>
<!-- arrow → Loading (purple) -->
<!-- arrow to recall -->
<line x1="290" y1="122" x2="317" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Loading (s09) ===== -->
<!-- ===== Recall ===== -->
<rect x="320" y="86" width="120" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Loading</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">LLM side-query select</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">inject file contents</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">≤ 5 items</text>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Recall</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">load selected records</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">add to system context</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">bounded body size</text>
<!-- arrow → LLM -->
<line x1="440" y1="122" x2="472" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- ===== LLM (s08) ===== -->
<!-- ===== LLM ===== -->
<rect x="475" y="96" width="80" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="515" y="114" fill="#1e3a5f" font-size="14" font-weight="700" text-anchor="middle">LLM</text>
<text x="515" y="132" fill="#64748b" font-size="9" text-anchor="middle">stop_reason</text>
@@ -70,19 +70,21 @@
<line x1="555" y1="122" x2="587" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="568" y="114" fill="#64748b" font-size="9" font-weight="600">yes</text>
<!-- ===== TOOL_HANDLERS (s08) ===== -->
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="590" y="88" width="130" height="68" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="655" y="112" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="655" y="128" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob · task</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob</text>
<!-- ===== Memory Files (s09) ===== -->
<rect x="155" y="232" width="430" height="36" rx="6" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="370" y="255" fill="#5b21b6" font-size="11" font-weight="600" text-anchor="middle">.memory/ — MEMORY.md index + *.md files (cross-session persistent)</text>
<!-- Arrow: Memory Files → Loading -->
<!-- Arrow: Memory Files to Selection -->
<path d="M 240 232 L 240 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="253" y="200" fill="#7c3aed" font-size="9">catalog</text>
<path d="M 395 232 L 395 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="408" y="200" fill="#7c3aed" font-size="9">read</text>
<text x="408" y="200" fill="#7c3aed" font-size="9">records</text>
<!-- Arrow: return result → Extraction → Memory Files -->
<path d="M 515 204 L 515 232" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
@@ -93,12 +95,12 @@
<!-- ===== Loop back ===== -->
<path d="M 720 122 L 748 122 Q 756 122 756 130 L 756 310 Q 756 318 748 318 L 88 318 Q 80 318 80 310 L 80 148" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">tool results → messages[] → compress → load memories → LLM → extract after each turn</text>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">tool result → messages[] → select → recall → LLM → extract after the turn</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="358" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="372" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="382" fill="#475569" font-size="10">s08 preserved: budget → snip → micro → summary + error recovery + loop</text>
<text x="80" y="382" fill="#475569" font-size="10">Agent Loop: messages → LLM → tool_use → tool result → messages</text>
<rect x="60" y="392" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="80" y="402" fill="#475569" font-size="10">s09 new: Loading (index in SYSTEM + on-demand inject) + Extraction (after each turn) + Consolidation (threshold)</text>
<text x="80" y="402" fill="#475569" font-size="10">Memory: select records → recall bodies → extract durable knowledge → consolidate at threshold</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -19,42 +19,42 @@
<!-- Title -->
<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">Memory — s08 圧縮パイプラインに記憶の読み込み・抽出・整理を挿入</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Memory — 保存・想起・抽出・整理</text>
<!-- Legend -->
<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">s08 維持</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">Agent Loop</text>
<rect x="130" y="56" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="148" y="66" fill="#7c3aed" font-size="10" font-weight="600">s09 追加</text>
<text x="148" y="66" fill="#7c3aed" font-size="10" font-weight="600">Memory</text>
<!-- ===== messages[] ===== -->
<rect x="30" y="96" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="126" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- arrow → compression -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- arrow to selection -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Compression pipeline (s08) ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="222" y="108" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">圧縮パイプライン</text>
<text x="222" y="124" fill="#64748b" font-size="9" text-anchor="middle">budget → snip → micro</text>
<text x="222" y="138" fill="#64748b" font-size="9" text-anchor="middle">→ compact_history</text>
<text x="222" y="152" fill="#94a3b8" font-size="8" text-anchor="middle">(s08)</text>
<!-- ===== Selection ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="222" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">選択</text>
<text x="222" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">catalog + 現在の request</text>
<text x="222" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">モデルまたは keyword</text>
<text x="222" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">最大 5 件</text>
<!-- arrow → Loading (purple) -->
<!-- arrow to recall -->
<line x1="290" y1="122" x2="317" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Loading (s09) ===== -->
<!-- ===== Recall ===== -->
<rect x="320" y="86" width="120" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Loading</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">LLM side-query 選択</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">ファイル内容を注入</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">≤ 5 件</text>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Recall</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">選択した record を読む</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">system context へ追加</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">本文サイズを制限</text>
<!-- arrow → LLM -->
<line x1="440" y1="122" x2="472" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- ===== LLM (s08) ===== -->
<!-- ===== LLM ===== -->
<rect x="475" y="96" width="80" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="515" y="114" fill="#1e3a5f" font-size="14" font-weight="700" text-anchor="middle">LLM</text>
<text x="515" y="132" fill="#64748b" font-size="9" text-anchor="middle">stop_reason</text>
@@ -70,19 +70,21 @@
<line x1="555" y1="122" x2="587" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="568" y="114" fill="#64748b" font-size="9" font-weight="600">あり</text>
<!-- ===== TOOL_HANDLERS (s08) ===== -->
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="590" y="88" width="130" height="68" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="655" y="112" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="655" y="128" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob · task</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob</text>
<!-- ===== Memory Files (s09) ===== -->
<rect x="155" y="232" width="430" height="36" rx="6" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="370" y="255" fill="#5b21b6" font-size="11" font-weight="600" text-anchor="middle">.memory/ — MEMORY.md インデックス + *.md ファイル(セッション間永続化)</text>
<!-- Arrow: Memory Files → Loading -->
<!-- Arrow: Memory Files to Selection -->
<path d="M 240 232 L 240 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="253" y="200" fill="#7c3aed" font-size="9">catalog</text>
<path d="M 395 232 L 395 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="408" y="200" fill="#7c3aed" font-size="9">読み込み</text>
<text x="408" y="200" fill="#7c3aed" font-size="9">record</text>
<!-- Arrow: return result → Extraction → Memory Files -->
<path d="M 515 204 L 515 232" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
@@ -93,12 +95,12 @@
<!-- ===== Loop back ===== -->
<path d="M 720 122 L 748 122 Q 756 122 756 130 L 756 310 Q 756 318 748 318 L 88 318 Q 80 318 80 310 L 80 148" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">ツール結果 → messages[] → 圧縮記憶読み込み → LLM → 毎ターン終了後に抽出</text>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">tool result → messages[] → 選択recall → LLM → turn 終了後に抽出</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="358" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="372" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="382" fill="#475569" font-size="10">s08 維持budgetsnip → micro → summary + エラー回復 + ループ</text>
<text x="80" y="382" fill="#475569" font-size="10">Agent LoopmessagesLLM → tool_use → tool result → messages</text>
<rect x="60" y="392" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="80" y="402" fill="#475569" font-size="10">s09 追加Loadingインデックス常駐 + オンデマンド注入)+ Extraction毎ターン終了後+ Consolidation閾値トリガー</text>
<text x="80" y="402" fill="#475569" font-size="10">Memoryrecord 選択 → 本文 recall → 永続知識を抽出 → threshold で整理</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -19,42 +19,42 @@
<!-- Title -->
<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">Memory — 在 s08 压缩管线上,插入记忆加载、提取与整理</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Memory — 存储、召回、提取与整理</text>
<!-- Legend -->
<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">s08 保留</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">Agent Loop</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="158" y="66" fill="#7c3aed" font-size="10" font-weight="600">s09 新增</text>
<text x="158" y="66" fill="#7c3aed" font-size="10" font-weight="600">Memory</text>
<!-- ===== messages[] ===== -->
<rect x="30" y="96" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="126" fill="#1e3a5f" font-size="12" font-weight="600" text-anchor="middle">messages[]</text>
<!-- arrow → compression -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- arrow to selection -->
<line x1="130" y1="122" x2="152" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Compression pipeline (s08) ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="222" y="108" fill="#1e3a5f" font-size="11" font-weight="700" text-anchor="middle">压缩管线</text>
<text x="222" y="124" fill="#64748b" font-size="9" text-anchor="middle">budget → snip → micro</text>
<text x="222" y="138" fill="#64748b" font-size="9" text-anchor="middle">→ compact_history</text>
<text x="222" y="152" fill="#94a3b8" font-size="8" text-anchor="middle">(s08)</text>
<!-- ===== Selection ===== -->
<rect x="155" y="86" width="135" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="222" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">选择</text>
<text x="222" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">目录 + 当前请求</text>
<text x="222" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">模型或关键词匹配</text>
<text x="222" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">≤ 5 条</text>
<!-- arrow → Loading (purple) -->
<!-- arrow to recall -->
<line x1="290" y1="122" x2="317" y2="122" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<!-- ===== Loading (s09) ===== -->
<!-- ===== Recall ===== -->
<rect x="320" y="86" width="120" height="72" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">Loading</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">LLM side-query 选文件</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">注入文件内容</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">≤ 5 条</text>
<text x="380" y="108" fill="#5b21b6" font-size="11" font-weight="700" text-anchor="middle">召回</text>
<text x="380" y="124" fill="#7c3aed" font-size="9" text-anchor="middle">读取选中的文件</text>
<text x="380" y="138" fill="#7c3aed" font-size="9" text-anchor="middle">加入 system context</text>
<text x="380" y="152" fill="#a78bfa" font-size="8" text-anchor="middle">正文总量受限</text>
<!-- arrow → LLM -->
<line x1="440" y1="122" x2="472" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- ===== LLM (s08) ===== -->
<!-- ===== LLM ===== -->
<rect x="475" y="96" width="80" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="515" y="114" fill="#1e3a5f" font-size="14" font-weight="700" text-anchor="middle">LLM</text>
<text x="515" y="132" fill="#64748b" font-size="9" text-anchor="middle">stop_reason</text>
@@ -70,19 +70,21 @@
<line x1="555" y1="122" x2="587" y2="122" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="568" y="114" fill="#64748b" font-size="9" font-weight="600"></text>
<!-- ===== TOOL_HANDLERS (s08) ===== -->
<!-- ===== TOOL_HANDLERS ===== -->
<rect x="590" y="88" width="130" height="68" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="655" y="112" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="655" y="128" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob · task</text>
<text x="655" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">edit · glob</text>
<!-- ===== Memory Files (s09) ===== -->
<rect x="155" y="232" width="430" height="36" rx="6" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="370" y="255" fill="#5b21b6" font-size="11" font-weight="600" text-anchor="middle">.memory/ — MEMORY.md 索引 + *.md 文件(跨会话持久化)</text>
<!-- Arrow: Memory Files → Loading -->
<!-- Arrow: Memory Files to Selection -->
<path d="M 240 232 L 240 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="253" y="200" fill="#7c3aed" font-size="9">目录</text>
<path d="M 395 232 L 395 162" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
<text x="408" y="200" fill="#7c3aed" font-size="9">读取</text>
<text x="408" y="200" fill="#7c3aed" font-size="9">正文</text>
<!-- Arrow: 返回结果 → Extraction → Memory Files -->
<path d="M 515 204 L 515 232" fill="none" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow-purple)"/>
@@ -93,12 +95,12 @@
<!-- ===== Loop back ===== -->
<path d="M 720 122 L 748 122 Q 756 122 756 130 L 756 310 Q 756 318 748 318 L 88 318 Q 80 318 80 310 L 80 148" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">工具结果追加到 messages[] → 压缩加载记忆 → LLM → 每轮结束后提取</text>
<text x="400" y="340" fill="#64748b" font-size="10" text-anchor="middle">工具结果 messages[] → 选择召回 → LLM → 回合结束后提取</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="358" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="372" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="382" fill="#475569" font-size="10">s08 保留budgetsnip → micro → summary + 错误后补救 + 循环</text>
<text x="80" y="382" fill="#475569" font-size="10">Agent LoopmessagesLLM → tool_use → 工具结果 → messages</text>
<rect x="60" y="392" width="12" height="10" rx="2" fill="#f3e8ff" stroke="#7c3aed" stroke-width="1"/>
<text x="80" y="402" fill="#475569" font-size="10">s09 新增Loading索引常驻 + 按需注入)+ Extraction每轮结束后+ Consolidation阈值触发</text>
<text x="80" y="402" fill="#475569" font-size="10">Memory选择相关记录 → 召回正文 → 提取持久知识 → 达到阈值后整理</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 380" font-family="system-ui, -apple-system, sans-serif">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 300" 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"/>
@@ -8,10 +8,10 @@
</marker>
</defs>
<rect width="720" height="380" fill="#fafbfc" rx="8"/>
<rect width="720" height="300" 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">Memory System — Store · Load · Extract · Consolidate</text>
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Memory System — Store · Recall · Extract · Consolidate</text>
<!-- Storage -->
<rect x="40" y="58" width="145" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
@@ -22,12 +22,12 @@
<line x1="190" y1="98" x2="218" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- Loading -->
<!-- Recall -->
<rect x="222" y="58" width="200" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">Load</text>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">Recall</text>
<line x1="237" y1="90" x2="407" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="237" y="108" fill="#5b21b6" font-size="10">Index in SYSTEM (always)</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">LLM side-query select files</text>
<text x="237" y="108" fill="#5b21b6" font-size="10">Index in the system prompt</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">Model selects relevant files</text>
<text x="237" y="134" fill="#a78bfa" font-size="9">≤ 5 items, fallback to keyword</text>
<line x1="425" y1="98" x2="453" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
@@ -36,9 +36,9 @@
<rect x="457" y="58" width="130" height="80" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="522" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">Extract</text>
<line x1="472" y1="90" x2="572" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="472" y="106" fill="#5b21b6" font-size="9.5">After each turn</text>
<text x="472" y="121" fill="#5b21b6" font-size="9.5">Extract prefs</text>
<text x="472" y="134" fill="#a78bfa" font-size="8.5">Avoid duplicates</text>
<text x="472" y="106" fill="#5b21b6" font-size="9.5">After the turn</text>
<text x="472" y="121" fill="#5b21b6" font-size="9.5">Extract durable knowledge</text>
<text x="472" y="134" fill="#a78bfa" font-size="8.5">Scope + duplicate checks</text>
<!-- Consolidation -->
<rect x="600" y="58" width="100" height="80" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2"/>
@@ -46,7 +46,7 @@
<line x1="615" y1="90" x2="685" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="615" y="106" fill="#5b21b6" font-size="9.5">≥ 10 files</text>
<text x="615" y="121" fill="#5b21b6" font-size="9.5">Dedup · merge</text>
<text x="615" y="134" fill="#a78bfa" font-size="8.5">CC: gated Dream</text>
<text x="615" y="134" fill="#a78bfa" font-size="8.5">Snapshot + rollback</text>
<!-- Memory Files -->
<rect x="40" y="180" width="660" height="36" rx="6" fill="#f8fafc" stroke="#94a3b8" stroke-width="1" stroke-dasharray="4,2"/>
@@ -69,10 +69,4 @@
<text x="60" y="260" fill="#5b21b6" font-size="10" font-weight="600">Four types:</text>
<text x="140" y="260" fill="#475569" font-size="10">user (who you are) · feedback (how to work) · project (what's happening) · reference (where to find things)</text>
<!-- CC source comparison -->
<rect x="40" y="296" width="660" height="72" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="316" fill="#5b21b6" font-size="11" font-weight="600">CC Source Comparison</text>
<text x="60" y="334" fill="#475569" font-size="10">• Selection: LLM side-query (Sonnet selects), not embedding vector similarity</text>
<text x="60" y="350" fill="#475569" font-size="10">• Extraction timing: stop hook after each turn, separate from compact_history</text>
<text x="60" y="365" fill="#475569" font-size="10">• Dream: time + sessions + file lock, not simple count</text>
</svg>

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 380" font-family="system-ui, -apple-system, sans-serif">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 300" 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"/>
@@ -8,10 +8,10 @@
</marker>
</defs>
<rect width="720" height="380" fill="#fafbfc" rx="8"/>
<rect width="720" height="300" 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">Memory System — ストレージ · 読み込み · 抽出 · 整理</text>
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Memory System — 保存 · Recall · 抽出 · 整理</text>
<!-- ストレージ -->
<rect x="40" y="58" width="145" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
@@ -22,12 +22,12 @@
<line x1="190" y1="98" x2="218" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- 読み込み -->
<!-- Recall -->
<rect x="222" y="58" width="200" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">読み込み</text>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">Recall</text>
<line x1="237" y1="90" x2="407" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="237" y="108" fill="#5b21b6" font-size="10">インデックスを SYSTEM に常駐</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">LLM side-query でファイル選択</text>
<text x="237" y="108" fill="#5b21b6" font-size="10">index を system prompt へ追加</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">モデルが関連ファイル選択</text>
<text x="237" y="134" fill="#a78bfa" font-size="9">≤ 5 件、失敗時はキーワードに降格</text>
<line x1="425" y1="98" x2="453" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
@@ -36,9 +36,9 @@
<rect x="457" y="58" width="130" height="80" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="522" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">抽出</text>
<line x1="472" y1="90" x2="572" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="472" y="106" fill="#5b21b6" font-size="9.5">毎ターン終了後</text>
<text x="472" y="121" fill="#5b21b6" font-size="9.5">好み/制約を抽出</text>
<text x="472" y="134" fill="#a78bfa" font-size="8.5">重複を回避</text>
<text x="472" y="106" fill="#5b21b6" font-size="9.5">turn 終了後</text>
<text x="472" y="121" fill="#5b21b6" font-size="9.5">永続知識を抽出</text>
<text x="472" y="134" fill="#a78bfa" font-size="8.5">scope + 重複確認</text>
<!-- 整理 -->
<rect x="600" y="58" width="100" height="80" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2"/>
@@ -46,7 +46,7 @@
<line x1="615" y1="90" x2="685" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="615" y="106" fill="#5b21b6" font-size="9.5">≥ 10 ファイル</text>
<text x="615" y="121" fill="#5b21b6" font-size="9.5">重複排除・統合</text>
<text x="615" y="134" fill="#a78bfa" font-size="8.5">CC: Dream ゲート</text>
<text x="615" y="134" fill="#a78bfa" font-size="8.5">snapshot + rollback</text>
<!-- Memory Files -->
<rect x="40" y="180" width="660" height="36" rx="6" fill="#f8fafc" stroke="#94a3b8" stroke-width="1" stroke-dasharray="4,2"/>
@@ -69,10 +69,4 @@
<text x="60" y="260" fill="#5b21b6" font-size="10" font-weight="600">4 種類の記憶:</text>
<text x="148" y="260" fill="#475569" font-size="10">userあなたは誰か· feedbackどう作業するか· project何が起きているか· referenceどこで探すか</text>
<!-- CC ソースコード対照 -->
<rect x="40" y="296" width="660" height="72" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="316" fill="#5b21b6" font-size="11" font-weight="600">CC ソースコード対照</text>
<text x="60" y="334" fill="#475569" font-size="10">• 記憶選択LLM side-querySonnet が選択、embedding ベクトル類似度ではない</text>
<text x="60" y="350" fill="#475569" font-size="10">• 抽出タイミング:各ターン終了時の stop hook、compact_history とは別に実行</text>
<text x="60" y="365" fill="#475569" font-size="10">• Dream時間・セッション・ロックで判定</text>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 380" font-family="system-ui, -apple-system, sans-serif">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 300" 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"/>
@@ -8,10 +8,10 @@
</marker>
</defs>
<rect width="720" height="380" fill="#fafbfc" rx="8"/>
<rect width="720" height="300" 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">Memory System — 存储 · 加载 · 提取 · 整理</text>
<text x="360" y="25" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">Memory System — 存储 · 召回 · 提取 · 整理</text>
<!-- 存储 -->
<rect x="40" y="58" width="145" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
@@ -22,12 +22,12 @@
<line x1="190" y1="98" x2="218" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- 加载 -->
<!-- 召回 -->
<rect x="222" y="58" width="200" height="80" rx="8" fill="#ede9fe" stroke="#7c3aed" stroke-width="2"/>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">加载</text>
<text x="322" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">召回</text>
<line x1="237" y1="90" x2="407" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="237" y="108" fill="#5b21b6" font-size="10">索引常驻 SYSTEM</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">LLM side-query 选文件</text>
<text x="237" y="108" fill="#5b21b6" font-size="10">索引加入 system prompt</text>
<text x="237" y="124" fill="#5b21b6" font-size="10">模型选择相关文件</text>
<text x="237" y="134" fill="#a78bfa" font-size="9">≤ 5 条,失败降级到关键词</text>
<line x1="425" y1="98" x2="453" y2="98" stroke="#7c3aed" stroke-width="1.5" marker-end="url(#arrow)"/>
@@ -36,9 +36,9 @@
<rect x="457" y="58" width="130" height="80" rx="8" fill="#f3e8ff" stroke="#7c3aed" stroke-width="2"/>
<text x="522" y="80" fill="#5b21b6" font-size="13" font-weight="700" text-anchor="middle">提取</text>
<line x1="472" y1="90" x2="572" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="472" y="108" fill="#5b21b6" font-size="10">每轮结束后触发</text>
<text x="472" y="124" fill="#5b21b6" font-size="10">LLM 提取偏好/约束</text>
<text x="472" y="134" fill="#a78bfa" font-size="9">检查已有,避免重复</text>
<text x="472" y="108" fill="#5b21b6" font-size="10">回合结束后触发</text>
<text x="472" y="124" fill="#5b21b6" font-size="10">模型提取持久知识</text>
<text x="472" y="134" fill="#a78bfa" font-size="9">scope + 重复检查</text>
<!-- 整理 -->
<rect x="600" y="58" width="100" height="80" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2"/>
@@ -46,7 +46,7 @@
<line x1="615" y1="90" x2="685" y2="90" stroke="#c4b5fd" stroke-width="0.5"/>
<text x="615" y="108" fill="#5b21b6" font-size="10">文件 ≥ 10 触发</text>
<text x="615" y="124" fill="#5b21b6" font-size="10">去重·合并·剪枝</text>
<text x="615" y="134" fill="#a78bfa" font-size="9">CC: 三层门控</text>
<text x="615" y="134" fill="#a78bfa" font-size="9">快照 + 失败恢复</text>
<!-- Memory Files -->
<rect x="40" y="180" width="660" height="36" rx="6" fill="#f8fafc" stroke="#94a3b8" stroke-width="1" stroke-dasharray="4,2"/>
@@ -69,10 +69,4 @@
<text x="60" y="260" fill="#5b21b6" font-size="10" font-weight="600">四类记忆:</text>
<text x="140" y="260" fill="#475569" font-size="10">user你是谁· feedback怎么做事· project正在发生什么· reference东西在哪找</text>
<!-- CC 源码对照 -->
<rect x="40" y="296" width="660" height="72" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="316" fill="#5b21b6" font-size="11" font-weight="600">CC 源码对照</text>
<text x="60" y="334" fill="#475569" font-size="10">• 记忆选择LLM side-querySonnet 选),不是 embedding 向量相似度</text>
<text x="60" y="350" fill="#475569" font-size="10">• 提取时机:每轮结束时由 stop hook 触发,与 compact_history 分开执行</text>
<text x="60" y="366" fill="#475569" font-size="10">• Dream 整理:三层门控(时间 ≥ 24h + 会话 ≥ 5 + 文件锁),不是简单计数</text>
</svg>

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -1,107 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 420" 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="#059669"/>
</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-green" 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="#059669"/>
</marker>
</defs>
<rect width="760" height="420" fill="#fafbfc" rx="8"/>
<!-- Title -->
<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">System Prompt — PROMPT_SECTIONS + On-Demand Assembly + Cache</text>
<!-- Legend -->
<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">s09 Preserved</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="178" y="66" fill="#059669" font-size="10" font-weight="600">s10 New</text>
<!-- ===== Prompt Assembly (green, s10) ===== -->
<!-- PROMPT_SECTIONS -->
<rect x="40" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="125" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">PROMPT_SECTIONS</text>
<text x="55" y="116" fill="#065f46" font-size="9">✓ identity (always)</text>
<text x="55" y="130" fill="#065f46" font-size="9">✓ tools (always)</text>
<text x="55" y="144" fill="#065f46" font-size="9">✓ workspace (always)</text>
<text x="55" y="158" fill="#6b7280" font-size="9">○ memory</text>
<!-- arrow → assemble -->
<line x1="210" y1="126" x2="235" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- assemble_system_prompt -->
<rect x="238" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="323" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">assemble_system_prompt</text>
<text x="253" y="118" fill="#065f46" font-size="9">Input: context dict</text>
<text x="253" y="132" fill="#065f46" font-size="9">Always: identity + tools + workspace</text>
<text x="253" y="146" fill="#065f46" font-size="9">On-demand: memory</text>
<text x="253" y="160" fill="#6b7280" font-size="9">Output: "\n\n".join(selected)</text>
<!-- arrow → cache -->
<line x1="408" y1="126" x2="433" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- get_system_prompt -->
<rect x="436" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="521" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">get_system_prompt</text>
<text x="451" y="118" fill="#065f46" font-size="9">json.dumps(context)</text>
<text x="451" y="132" fill="#065f46" font-size="9">Hit → return cached</text>
<text x="451" y="146" fill="#065f46" font-size="9">Miss → assemble + store</text>
<text x="451" y="160" fill="#6b7280" font-size="9">(s10 new)</text>
<!-- Arrow: cache → LLM -->
<path d="M 521 170 L 521 195 L 410 195 L 410 212" fill="none" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<text x="462" y="189" fill="#059669" font-size="9">system=get_system_prompt(context)</text>
<!-- ===== s09 Agent Loop (blue) ===== -->
<!-- messages[] -->
<rect x="30" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="241" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">messages[]</text>
<!-- arrow → compression+loading -->
<line x1="130" y1="237" x2="155" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- compression + loading -->
<rect x="158" y="206" width="170" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="243" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">Compression + Loading</text>
<text x="243" y="242" fill="#64748b" font-size="9" text-anchor="middle">snip → micro → budget → auto</text>
<text x="243" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">→ load memory (s09)</text>
<!-- arrow → LLM -->
<line x1="328" y1="237" x2="358" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM -->
<rect x="360" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="410" y="231" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">LLM</text>
<text x="410" y="246" fill="#64748b" font-size="8" text-anchor="middle">stop_reason=tool_use?</text>
<text x="410" y="258" fill="#059669" font-size="8" text-anchor="middle">system assembled</text>
<!-- arrow → TOOLS -->
<line x1="460" y1="237" x2="490" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="466" y="229" fill="#64748b" font-size="8">yes</text>
<!-- TOOL_HANDLERS -->
<rect x="493" y="206" width="130" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="558" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="558" y="242" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="558" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">(s09 preserved)</text>
<!-- ===== Loop back ===== -->
<path d="M 623 237 L 660 237 L 660 312 L 80 312 L 80 260" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="370" y="328" fill="#64748b" font-size="10" text-anchor="middle">Tool results → messages[] → compress → load memory → assemble prompt → LLM</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="350" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="362" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="372" fill="#475569" font-size="10">s09 Preserved: loop, compression pipeline, memory loading, tool execution</text>
<rect x="60" y="382" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="80" y="392" fill="#475569" font-size="10">s10 New: PROMPT_SECTIONS (4 sections) + assemble_system_prompt + get_system_prompt (cache)</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -1,107 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 420" 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="#059669"/>
</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-green" 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="#059669"/>
</marker>
</defs>
<rect width="760" height="420" 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">System Prompt — PROMPT_SECTIONS + オンデマンド組み立て + キャッシュ</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">s09 保持</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="158" y="66" fill="#059669" font-size="10" font-weight="600">s10 新規</text>
<!-- ===== プロンプトアセンブリ緑、s10 ===== -->
<!-- PROMPT_SECTIONS -->
<rect x="40" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="125" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">PROMPT_SECTIONS</text>
<text x="55" y="116" fill="#065f46" font-size="9">✓ identity (常時)</text>
<text x="55" y="130" fill="#065f46" font-size="9">✓ tools (常時)</text>
<text x="55" y="144" fill="#065f46" font-size="9">✓ workspace (常時)</text>
<text x="55" y="158" fill="#6b7280" font-size="9">○ memory</text>
<!-- 矢印 → assemble -->
<line x1="210" y1="126" x2="235" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- assemble_system_prompt -->
<rect x="238" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="323" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">assemble_system_prompt</text>
<text x="253" y="118" fill="#065f46" font-size="9">入力: context dict</text>
<text x="253" y="132" fill="#065f46" font-size="9">常時: identity + tools + workspace</text>
<text x="253" y="146" fill="#065f46" font-size="9">オンデマンド: memory</text>
<text x="253" y="160" fill="#6b7280" font-size="9">出力: "\n\n".join(selected)</text>
<!-- 矢印 → cache -->
<line x1="408" y1="126" x2="433" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- get_system_prompt -->
<rect x="436" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="521" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">get_system_prompt</text>
<text x="451" y="118" fill="#065f46" font-size="9">json.dumps(context)</text>
<text x="451" y="132" fill="#065f46" font-size="9">ヒット → キャッシュ返却</text>
<text x="451" y="146" fill="#065f46" font-size="9">ミス → assemble + 保存</text>
<text x="451" y="160" fill="#6b7280" font-size="9">(s10 新規)</text>
<!-- 矢印: cache → LLM -->
<path d="M 521 170 L 521 195 L 410 195 L 410 212" fill="none" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<text x="462" y="189" fill="#059669" font-size="9">system=get_system_prompt(context)</text>
<!-- ===== s09 Agent Loop ===== -->
<!-- messages[] -->
<rect x="30" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="241" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">messages[]</text>
<!-- 矢印 → compression+loading -->
<line x1="130" y1="237" x2="155" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- 圧縮 + ロード -->
<rect x="158" y="206" width="170" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="243" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">圧縮 + ロード</text>
<text x="243" y="242" fill="#64748b" font-size="9" text-anchor="middle">snip → micro → budget → auto</text>
<text x="243" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">→ 記憶ロード (s09)</text>
<!-- 矢印 → LLM -->
<line x1="328" y1="237" x2="358" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM -->
<rect x="360" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="410" y="231" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">LLM</text>
<text x="410" y="246" fill="#64748b" font-size="8" text-anchor="middle">stop_reason=tool_use?</text>
<text x="410" y="258" fill="#059669" font-size="8" text-anchor="middle">system assembled</text>
<!-- 矢印 → TOOLS -->
<line x1="460" y1="237" x2="490" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="466" y="229" fill="#64748b" font-size="8">あり</text>
<!-- TOOL_HANDLERS -->
<rect x="493" y="206" width="130" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="558" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="558" y="242" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="558" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">(s09 保持)</text>
<!-- ===== ループバック ===== -->
<path d="M 623 237 L 660 237 L 660 312 L 80 312 L 80 260" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="370" y="328" fill="#64748b" font-size="10" text-anchor="middle">ツール結果 → messages[] → 圧縮 → 記憶ロード → プロンプト組み立て → LLM</text>
<!-- ===== 下部ノート ===== -->
<rect x="40" y="350" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="362" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="372" fill="#475569" font-size="10">s09 保持:ループ、圧縮パイプライン、記憶ロード、ツール実行</text>
<rect x="60" y="382" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="80" y="392" fill="#475569" font-size="10">s10 新規PROMPT_SECTIONS4 セクション)+ assemble_system_prompt + get_system_promptキャッシュ</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1,107 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 420" 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="#059669"/>
</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-green" 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="#059669"/>
</marker>
</defs>
<rect width="760" height="420" fill="#fafbfc" rx="8"/>
<!-- Title -->
<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">System Prompt — PROMPT_SECTIONS + 按需拼接 + 缓存</text>
<!-- Legend -->
<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">s09 保留</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="158" y="66" fill="#059669" font-size="10" font-weight="600">s10 新增</text>
<!-- ===== Prompt Assembly (green, s10) ===== -->
<!-- PROMPT_SECTIONS -->
<rect x="40" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="125" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">PROMPT_SECTIONS</text>
<text x="55" y="116" fill="#065f46" font-size="9">✓ identity (始终)</text>
<text x="55" y="130" fill="#065f46" font-size="9">✓ tools (始终)</text>
<text x="55" y="144" fill="#065f46" font-size="9">✓ workspace (始终)</text>
<text x="55" y="158" fill="#6b7280" font-size="9">○ memory</text>
<!-- arrow → assemble -->
<line x1="210" y1="126" x2="235" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- assemble_system_prompt -->
<rect x="238" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="323" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">assemble_system_prompt</text>
<text x="253" y="118" fill="#065f46" font-size="9">输入: context dict</text>
<text x="253" y="132" fill="#065f46" font-size="9">始终: identity + tools + workspace</text>
<text x="253" y="146" fill="#065f46" font-size="9">按需: memory</text>
<text x="253" y="160" fill="#6b7280" font-size="9">输出: "\n\n".join(selected)</text>
<!-- arrow → cache -->
<line x1="408" y1="126" x2="433" y2="126" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<!-- get_system_prompt -->
<rect x="436" y="82" width="170" height="88" rx="8" fill="#ecfdf5" stroke="#059669" stroke-width="2"/>
<text x="521" y="100" fill="#065f46" font-size="11" font-weight="700" text-anchor="middle">get_system_prompt</text>
<text x="451" y="118" fill="#065f46" font-size="9">json.dumps(context)</text>
<text x="451" y="132" fill="#065f46" font-size="9">命中 → 返回缓存</text>
<text x="451" y="146" fill="#065f46" font-size="9">未命中 → assemble + 存</text>
<text x="451" y="160" fill="#6b7280" font-size="9">(s10 新增)</text>
<!-- Arrow: cache → LLM -->
<path d="M 521 170 L 521 195 L 410 195 L 410 212" fill="none" stroke="#059669" stroke-width="1.5" marker-end="url(#arrow-green)"/>
<text x="462" y="189" fill="#059669" font-size="9">system=get_system_prompt(context)</text>
<!-- ===== s09 Agent Loop (blue) ===== -->
<!-- messages[] -->
<rect x="30" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="80" y="241" fill="#1e3a5f" font-size="11" font-weight="600" text-anchor="middle">messages[]</text>
<!-- arrow → compression+loading -->
<line x1="130" y1="237" x2="155" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- compression + loading -->
<rect x="158" y="206" width="170" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="243" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">压缩 + Loading</text>
<text x="243" y="242" fill="#64748b" font-size="9" text-anchor="middle">snip → micro → budget → auto</text>
<text x="243" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">→ 加载记忆 (s09)</text>
<!-- arrow → LLM -->
<line x1="328" y1="237" x2="358" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM -->
<rect x="360" y="214" width="100" height="46" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="410" y="231" fill="#1e3a5f" font-size="12" font-weight="700" text-anchor="middle">LLM</text>
<text x="410" y="246" fill="#64748b" font-size="8" text-anchor="middle">stop_reason=tool_use?</text>
<text x="410" y="258" fill="#059669" font-size="8" text-anchor="middle">system assembled</text>
<!-- arrow → TOOLS -->
<line x1="460" y1="237" x2="490" y2="237" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="466" y="229" fill="#64748b" font-size="8"></text>
<!-- TOOL_HANDLERS -->
<rect x="493" y="206" width="130" height="62" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="558" y="228" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="558" y="242" fill="#64748b" font-size="9" text-anchor="middle">bash · read · write</text>
<text x="558" y="256" fill="#94a3b8" font-size="8" text-anchor="middle">(s09 保留)</text>
<!-- ===== Loop back ===== -->
<path d="M 623 237 L 660 237 L 660 312 L 80 312 L 80 260" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
<text x="370" y="328" fill="#64748b" font-size="10" text-anchor="middle">工具结果 → messages[] → 压缩 → 加载记忆 → 组装 prompt → LLM</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="350" width="680" height="56" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="362" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="372" fill="#475569" font-size="10">s09 保留:循环、压缩管线、记忆加载、工具执行</text>
<rect x="60" y="382" width="12" height="10" rx="2" fill="#ecfdf5" stroke="#059669" stroke-width="1"/>
<text x="80" y="392" fill="#475569" font-size="10">s10 新增PROMPT_SECTIONS4 段)+ assemble_system_prompt + get_system_prompt缓存</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -20,32 +20,32 @@
<!-- Legend -->
<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">s11 Preserved</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">Base Loop</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="178" y="66" fill="#0d9488" font-size="10" font-weight="600">s12 New</text>
<text x="178" y="66" fill="#0d9488" font-size="10" font-weight="600">s10 New</text>
<!-- ===== s11 loop (compact) ===== -->
<!-- ===== base loop (compact) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + compress</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s11)</text>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="112" x2="269" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="112" x2="390" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOLS (expanded) -->
<rect x="393" y="80" width="210" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write</text>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">Hooks + TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write · edit · glob</text>
<text x="408" y="128" fill="#0d9488" font-size="9" font-weight="600">create_task · list_tasks</text>
<text x="408" y="140" fill="#0d9488" font-size="9" font-weight="600">get_task · claim_task · complete_task</text>
@@ -57,7 +57,7 @@
<text x="195" y="205" fill="#134e4a" font-size="11" font-weight="700" text-anchor="middle">.tasks/ — Cross-session Persistence</text>
<text x="60" y="222" fill="#0d9488" font-size="9">task_xxx.json · task_yyy.json · task_zzz.json</text>
<text x="60" y="238" fill="#6b7280" font-size="8">{id, subject, description, status, owner, blockedBy}</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: timestamp + random</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: task_ + 8 random hex characters</text>
<!-- Arrow: tools → .tasks/ -->
<path d="M 440 144 L 440 165 L 250 165 L 250 185" fill="none" stroke="#0d9488" stroke-width="1.5" marker-end="url(#arrow-teal)"/>
@@ -83,12 +83,12 @@
<text x="412" y="303" fill="#16a34a" font-size="8" font-weight="600" text-anchor="middle">complete_task</text>
<rect x="460" y="298" width="72" height="20" rx="4" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="496" y="312" fill="#166534" font-size="9" text-anchor="middle">completed</text>
<text x="548" y="312" fill="#94a3b8" font-size="9">No release rollback; crash → unassign owner</text>
<text x="548" y="312" fill="#94a3b8" font-size="9">complete_task checks status and owner</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="352" width="680" height="52" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="366" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="376" fill="#475569" font-size="10">s11 Preserved: loop, prompt assembly, compression (error recovery independent from task system)</text>
<text x="80" y="376" fill="#475569" font-size="10">Base loop: model call + Permission/Hooks + tool dispatch + tool_result</text>
<rect x="60" y="384" width="12" height="10" rx="2" fill="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="80" y="394" fill="#475569" font-size="10">s12 New: Task dataclass + 5 tools + .tasks/ persistence + blockedBy dependency graph</text>
<text x="80" y="394" fill="#475569" font-size="10">s10 New: Task dataclass + 5 tools + .tasks/ persistence + blockedBy dependency graph</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -20,32 +20,32 @@
<!-- 凡例 -->
<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">s11 保持</text>
<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="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="158" y="66" fill="#0d9488" font-size="10" font-weight="600">s12 新規</text>
<text x="158" y="66" fill="#0d9488" font-size="10" font-weight="600">s10 新規</text>
<!-- ===== s11 ループ(コンパクト) ===== -->
<!-- ===== 基本ループ(コンパクト) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + compress</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s11)</text>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="112" x2="269" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="112" x2="390" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- ツール(展開) -->
<rect x="393" y="80" width="210" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write</text>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">Hooks + TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write · edit · glob</text>
<text x="408" y="128" fill="#0d9488" font-size="9" font-weight="600">create_task · list_tasks</text>
<text x="408" y="140" fill="#0d9488" font-size="9" font-weight="600">get_task · claim_task · complete_task</text>
@@ -57,7 +57,7 @@
<text x="195" y="205" fill="#134e4a" font-size="11" font-weight="700" text-anchor="middle">.tasks/ — セッション横断永続化</text>
<text x="60" y="222" fill="#0d9488" font-size="9">task_xxx.json · task_yyy.json · task_zzz.json</text>
<text x="60" y="238" fill="#6b7280" font-size="8">{id, subject, description, status, owner, blockedBy}</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: timestamp + random</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: task_ + 8 桁のランダムな 16 進文字</text>
<!-- 矢印: tools → .tasks/ -->
<path d="M 440 144 L 440 165 L 250 165 L 250 185" fill="none" stroke="#0d9488" stroke-width="1.5" marker-end="url(#arrow-teal)"/>
@@ -83,12 +83,12 @@
<text x="402" y="303" fill="#16a34a" font-size="8" font-weight="600" text-anchor="middle">complete_task</text>
<rect x="450" y="298" width="72" height="20" rx="4" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="486" y="312" fill="#166534" font-size="9" text-anchor="middle">completed</text>
<text x="538" y="312" fill="#94a3b8" font-size="9">release ロールバックなし、クラッシュ時は unassign で owner クリア</text>
<text x="538" y="312" fill="#94a3b8" font-size="9">complete_task は status と owner を確認</text>
<!-- ===== 下部ノート ===== -->
<rect x="40" y="352" width="680" height="52" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="366" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="376" fill="#475569" font-size="10">s11 保持:ループ、プロンプト組み立て、圧縮(エラーリカバリとタスクシステムは独立)</text>
<text x="80" y="376" fill="#475569" font-size="10">基本ループ:モデル呼び出し + Permission/Hooks + ツール分配 + tool_result</text>
<rect x="60" y="384" width="12" height="10" rx="2" fill="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="80" y="394" fill="#475569" font-size="10">s12 新規Task dataclass + 5 ツール + .tasks/ 永続化 + blockedBy 依存グラフ</text>
<text x="80" y="394" fill="#475569" font-size="10">s10 新規Task dataclass + 5 ツール + .tasks/ 永続化 + blockedBy 依存グラフ</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -20,32 +20,32 @@
<!-- Legend -->
<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">s11 保留</text>
<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="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="158" y="66" fill="#0d9488" font-size="10" font-weight="600">s12 新增</text>
<text x="158" y="66" fill="#0d9488" font-size="10" font-weight="600">s10 新增</text>
<!-- ===== s11 loop (compact) ===== -->
<!-- ===== base loop (compact) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + compress</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s11)</text>
<text x="191" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="112" x2="269" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="322" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="112" x2="390" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOLS (expanded) -->
<rect x="393" y="80" width="210" height="64" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write</text>
<text x="498" y="98" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">Hooks + TOOL_HANDLERS</text>
<text x="408" y="114" fill="#2563eb" font-size="9">bash · read · write · edit · glob</text>
<text x="408" y="128" fill="#0d9488" font-size="9" font-weight="600">create_task · list_tasks</text>
<text x="408" y="140" fill="#0d9488" font-size="9" font-weight="600">get_task · claim_task · complete_task</text>
@@ -57,7 +57,7 @@
<text x="195" y="205" fill="#134e4a" font-size="11" font-weight="700" text-anchor="middle">.tasks/ — 跨会话持久化</text>
<text x="60" y="222" fill="#0d9488" font-size="9">task_xxx.json · task_yyy.json · task_zzz.json</text>
<text x="60" y="238" fill="#6b7280" font-size="8">{id, subject, description, status, owner, blockedBy}</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: timestamp + random</text>
<text x="60" y="252" fill="#6b7280" font-size="8">ID: task_ + 8 位随机十六进制字符</text>
<!-- Arrow: tools → .tasks/ -->
<path d="M 440 144 L 440 165 L 250 165 L 250 185" fill="none" stroke="#0d9488" stroke-width="1.5" marker-end="url(#arrow-teal)"/>
@@ -83,12 +83,12 @@
<text x="362" y="303" fill="#16a34a" font-size="8" font-weight="600" text-anchor="middle">complete_task</text>
<rect x="410" y="298" width="72" height="20" rx="4" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="446" y="312" fill="#166534" font-size="9" text-anchor="middle">completed</text>
<text x="500" y="312" fill="#94a3b8" font-size="9">CC 无 release 回退,崩溃时用 unassign 清 owner</text>
<text x="500" y="312" fill="#94a3b8" font-size="9">complete_task 检查 status 和 owner</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="352" width="680" height="52" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="60" y="366" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="80" y="376" fill="#475569" font-size="10">s11 保留循环、prompt 组装、压缩(错误恢复与任务系统独立)</text>
<text x="80" y="376" fill="#475569" font-size="10">基础循环:模型调用 + Permission/Hooks + 工具分发 + tool_result</text>
<rect x="60" y="384" width="12" height="10" rx="2" fill="#f0fdfa" stroke="#0d9488" stroke-width="1"/>
<text x="80" y="394" fill="#475569" font-size="10">s12 新增Task dataclass + 5 个工具 + .tasks/ 持久化 + blockedBy 依赖图</text>
<text x="80" y="394" fill="#475569" font-size="10">s10 新增Task dataclass + 5 个工具 + .tasks/ 持久化 + blockedBy 依赖图</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -16,37 +16,37 @@
<!-- Title -->
<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">Background Tasks — Slow ops to background, Agent keeps thinking</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Background Tasks — Slow ops in background, Agent Loop continues</text>
<!-- Legend -->
<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">s12 retained</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 kernel</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s13 new</text>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s11 new</text>
<!-- ===== Top: s12 loop (compact) ===== -->
<!-- ===== Top: s04 loop (compact) ===== -->
<rect x="30" y="86" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="110" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="106" x2="128" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="80" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s12)</text>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="106" x2="269" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="80" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s11 retry)</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="106" x2="390" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="393" y="76" width="210" height="60" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="408" y="110" fill="#2563eb" font-size="9">fast? → sync execute (s12)</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">slow? → run_in_background ★</text>
<text x="408" y="110" fill="#2563eb" font-size="9">background=false → sync execute</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">background=true → worker thread</text>
<!-- Loop back -->
<path d="M 603 106 L 640 106 L 640 148 L 70 148 L 70 126" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
@@ -54,7 +54,7 @@
<!-- ===== Background execution (orange) ===== -->
<rect x="40" y="172" width="310" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="195" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">Background thread execution</text>
<text x="60" y="212" fill="#ea580c" font-size="9">run_in_background(tool_use_id, fn, *args)</text>
<text x="60" y="212" fill="#ea580c" font-size="9">BackgroundManager.start(block)</text>
<text x="60" y="226" fill="#6b7280" font-size="8">threading.Thread(target=worker, daemon=True)</text>
<text x="60" y="240" fill="#6b7280" font-size="8">result → background_results[id] (threading.Lock protected)</text>
@@ -64,42 +64,42 @@
<!-- ===== Notification injection (orange) ===== -->
<rect x="390" y="172" width="330" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">Notification injection</text>
<text x="408" y="212" fill="#ea580c" font-size="9">collect_background_results() check each turn</text>
<text x="408" y="226" fill="#6b7280" font-size="8">completed → tool_result inject into messages</text>
<text x="408" y="240" fill="#6b7280" font-size="8">pending → "[Running in background...]" placeholder</text>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">Collect on later turn</text>
<text x="408" y="212" fill="#ea580c" font-size="9">collect_background_results() before LLM call</text>
<text x="408" y="226" fill="#6b7280" font-size="8">completed → task_notification added to messages</text>
<text x="408" y="240" fill="#6b7280" font-size="8">running → task state remains</text>
<!-- Arrow: background → notification -->
<path d="M 350 220 L 390 220" fill="none" stroke="#ea580c" stroke-width="1.5" marker-end="url(#arrow-orange)"/>
<!-- ===== Slow operation heuristic ===== -->
<!-- ===== Explicit execution choice ===== -->
<rect x="40" y="274" width="680" height="48" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">Heuristic:</text>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">Explicit flag:</text>
<rect x="155" y="284" width="56" height="18" rx="4" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1"/>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">fast</text>
<text x="218" y="297" fill="#475569" font-size="9">read_file · git status · glob</text>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">false</text>
<text x="218" y="297" fill="#475569" font-size="9">run_in_background=false · synchronous</text>
<rect x="360" y="284" width="56" height="18" rx="4" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">slow</text>
<text x="423" y="297" fill="#475569" font-size="9">npm install · pip install · pytest (timeout > 30s)</text>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">true</text>
<text x="423" y="297" fill="#475569" font-size="9">run_in_background=true · background</text>
<!-- ===== Timeline comparison ===== -->
<rect x="40" y="340" width="330" height="84" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s12 sync blocking</text>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s04 synchronous execution</text>
<rect x="60" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">think</text>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM call</text>
<rect x="145" y="370" width="160" height="14" rx="3" fill="#fecaca" stroke="#dc2626" stroke-width="1"/>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle">waiting for bash 3min...</text>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle">wait for bash result</text>
<rect x="310" y="370" width="40" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">continue</text>
<text x="60" y="410" fill="#991b1b" font-size="9">Total ~3min, Agent idled for 3 minutes</text>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">next turn</text>
<text x="60" y="410" fill="#991b1b" font-size="9">The loop continues after the command returns</text>
<rect x="390" y="340" width="330" height="84" rx="6" fill="#f0fdf4" stroke="#16a34a" stroke-width="1"/>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s13 background execution</text>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s11 background execution</text>
<rect x="410" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">think</text>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM call</text>
<rect x="495" y="370" width="100" height="14" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">keep doing other work</text>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">run other tools</text>
<rect x="600" y="370" width="100" height="14" rx="3" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">notification: result ready</text>
<text x="410" y="410" fill="#166534" font-size="9">Total ~3min, but Agent wasn't idle</text>
</svg>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">collect next turn</text>
<text x="410" y="410" fill="#166534" font-size="9">Bash runs on a background thread</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -16,37 +16,37 @@
<!-- Title -->
<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">Background Tasks — 遅い操作はバックグラウンドへ、Agent は考え続ける</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Background Tasks — 遅い操作はバックグラウンドへ、Agent Loop は継続</text>
<!-- Legend -->
<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">s12 維持</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 Kernel</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s13 新規</text>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s11 新規</text>
<!-- ===== Top: s12 loop (compact) ===== -->
<!-- ===== Top: s04 loop (compact) ===== -->
<rect x="30" y="86" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="110" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="106" x2="128" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="80" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s12)</text>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="106" x2="269" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="80" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s11 retry)</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="106" x2="390" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="393" y="76" width="210" height="60" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="408" y="110" fill="#2563eb" font-size="9">fast? → 同期実行 (s12)</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">slow? → run_in_background ★</text>
<text x="408" y="110" fill="#2563eb" font-size="9">background=false → 同期実行</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">background=true → worker thread</text>
<!-- Loop back -->
<path d="M 603 106 L 640 106 L 640 148 L 70 148 L 70 126" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
@@ -54,7 +54,7 @@
<!-- ===== Background execution (orange) ===== -->
<rect x="40" y="172" width="310" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="195" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">バックグラウンドスレッド実行</text>
<text x="60" y="212" fill="#ea580c" font-size="9">run_in_background(tool_use_id, fn, *args)</text>
<text x="60" y="212" fill="#ea580c" font-size="9">BackgroundManager.start(block)</text>
<text x="60" y="226" fill="#6b7280" font-size="8">threading.Thread(target=worker, daemon=True)</text>
<text x="60" y="240" fill="#6b7280" font-size="8">結果 → background_results[id] (threading.Lock で保護)</text>
@@ -64,42 +64,42 @@
<!-- ===== Notification injection (orange) ===== -->
<rect x="390" y="172" width="330" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">通知注入</text>
<text x="408" y="212" fill="#ea580c" font-size="9">collect_background_results() 毎ターン確認</text>
<text x="408" y="226" fill="#6b7280" font-size="8">完了 → tool_result を messages に注入</text>
<text x="408" y="240" fill="#6b7280" font-size="8">未完了 → "[Running in background...]" プレースホルダー</text>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">後続ターンで収集</text>
<text x="408" y="212" fill="#ea580c" font-size="9">LLM 呼び出し前に collect_background_results()</text>
<text x="408" y="226" fill="#6b7280" font-size="8">完了 → task_notification を messages に追加</text>
<text x="408" y="240" fill="#6b7280" font-size="8">実行中 → タスク状態を保持</text>
<!-- Arrow: background → notification -->
<path d="M 350 220 L 390 220" fill="none" stroke="#ea580c" stroke-width="1.5" marker-end="url(#arrow-orange)"/>
<!-- ===== Slow operation heuristic ===== -->
<!-- ===== Explicit execution choice ===== -->
<rect x="40" y="274" width="680" height="48" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">ヒューリスティック判定:</text>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">明示的な指定:</text>
<rect x="155" y="284" width="56" height="18" rx="4" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1"/>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">fast</text>
<text x="218" y="297" fill="#475569" font-size="9">read_file · git status · glob</text>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">false</text>
<text x="218" y="297" fill="#475569" font-size="9">run_in_background=false · 同期実行</text>
<rect x="360" y="284" width="56" height="18" rx="4" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">slow</text>
<text x="423" y="297" fill="#475569" font-size="9">npm install · pip install · pytest (timeout > 30s)</text>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">true</text>
<text x="423" y="297" fill="#475569" font-size="9">run_in_background=true · バックグラウンド</text>
<!-- ===== Timeline comparison ===== -->
<rect x="40" y="340" width="330" height="84" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s12 同期ブロッキング</text>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s04 同期実行</text>
<rect x="60" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">思考</text>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM 呼び出し</text>
<rect x="145" y="370" width="160" height="14" rx="3" fill="#fecaca" stroke="#dc2626" stroke-width="1"/>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle">bash 待ち 3分...</text>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle">bash の結果を待つ</text>
<rect x="310" y="370" width="40" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">継続</text>
<text x="60" y="410" fill="#991b1b" font-size="9">合計 ~3分、Agent は3分間待機</text>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">次のターン</text>
<text x="60" y="410" fill="#991b1b" font-size="9">コマンド終了後にループを継続</text>
<rect x="390" y="340" width="330" height="84" rx="6" fill="#f0fdf4" stroke="#16a34a" stroke-width="1"/>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s13 バックグラウンド実行</text>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s11 バックグラウンド実行</text>
<rect x="410" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">思考</text>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM 呼び出し</text>
<rect x="495" y="370" width="100" height="14" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">別の作業を継続</text>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">他のツールを実行</text>
<rect x="600" y="370" width="100" height="14" rx="3" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">通知: 結果完了</text>
<text x="410" y="410" fill="#166534" font-size="9">合計 ~3分、Agent は遊ばず</text>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">後続ターンで収集</text>
<text x="410" y="410" fill="#166534" font-size="9">bash はバックグラウンドスレッドで実行</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -16,37 +16,37 @@
<!-- Title -->
<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">Background Tasks — 慢操作后台Agent 继续思考</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Background Tasks — 慢操作后台Agent Loop 继续运行</text>
<!-- Legend -->
<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">s12 保留</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 Kernel</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s13 新增</text>
<text x="158" y="66" fill="#ea580c" font-size="10" font-weight="600">s11 新增</text>
<!-- ===== Top: s12 loop (compact) ===== -->
<!-- ===== Top: s04 loop (compact) ===== -->
<rect x="30" y="86" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="110" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="106" x2="128" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="80" width="120" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s10-s12)</text>
<text x="191" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="191" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">fixed instructions</text>
<line x1="251" y1="106" x2="269" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="272" y="80" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="322" y="102" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">(s11 retry)</text>
<text x="322" y="116" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="372" y1="106" x2="390" y2="106" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="393" y="76" width="210" height="60" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="498" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="408" y="110" fill="#2563eb" font-size="9">fast? → 同步执行 (s12)</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">slow? → run_in_background ★</text>
<text x="408" y="110" fill="#2563eb" font-size="9">background=false → 同步执行</text>
<text x="408" y="124" fill="#ea580c" font-size="9" font-weight="600">background=true → 后台线程</text>
<!-- Loop back -->
<path d="M 603 106 L 640 106 L 640 148 L 70 148 L 70 126" fill="none" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)" stroke-dasharray="6,3"/>
@@ -54,7 +54,7 @@
<!-- ===== Background execution (orange) ===== -->
<rect x="40" y="172" width="310" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="195" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">后台线程执行</text>
<text x="60" y="212" fill="#ea580c" font-size="9">run_in_background(tool_use_id, fn, *args)</text>
<text x="60" y="212" fill="#ea580c" font-size="9">BackgroundManager.start(block)</text>
<text x="60" y="226" fill="#6b7280" font-size="8">threading.Thread(target=worker, daemon=True)</text>
<text x="60" y="240" fill="#6b7280" font-size="8">结果 → background_results[id] (threading.Lock 保护)</text>
@@ -64,42 +64,42 @@
<!-- ===== Notification injection (orange) ===== -->
<rect x="390" y="172" width="330" height="80" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="2"/>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">通知注入</text>
<text x="408" y="212" fill="#ea580c" font-size="9">collect_background_results() 每轮检查</text>
<text x="408" y="226" fill="#6b7280" font-size="8">已完成 → tool_result 注入 messages</text>
<text x="408" y="240" fill="#6b7280" font-size="8">未完成 → "[Running in background...]" 占位</text>
<text x="555" y="194" fill="#9a3412" font-size="11" font-weight="700" text-anchor="middle">后续轮次收集</text>
<text x="408" y="212" fill="#ea580c" font-size="9">LLM 调用前 collect_background_results()</text>
<text x="408" y="226" fill="#6b7280" font-size="8">已完成 → task_notification 加入 messages</text>
<text x="408" y="240" fill="#6b7280" font-size="8">运行中 → 保留任务状态</text>
<!-- Arrow: background → notification -->
<path d="M 350 220 L 390 220" fill="none" stroke="#ea580c" stroke-width="1.5" marker-end="url(#arrow-orange)"/>
<!-- ===== Slow operation heuristic ===== -->
<!-- ===== Explicit execution choice ===== -->
<rect x="40" y="274" width="680" height="48" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">启发式判断:</text>
<text x="60" y="296" fill="#1e3a5f" font-size="11" font-weight="600">显式参数:</text>
<rect x="155" y="284" width="56" height="18" rx="4" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1"/>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">fast</text>
<text x="218" y="297" fill="#475569" font-size="9">read_file · git status · glob</text>
<text x="183" y="297" fill="#16a34a" font-size="9" text-anchor="middle">false</text>
<text x="218" y="297" fill="#475569" font-size="9">run_in_background=false · 同步执行</text>
<rect x="360" y="284" width="56" height="18" rx="4" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">slow</text>
<text x="423" y="297" fill="#475569" font-size="9">npm install · pip install · pytest (timeout > 30s)</text>
<text x="388" y="297" fill="#ea580c" font-size="9" text-anchor="middle">true</text>
<text x="423" y="297" fill="#475569" font-size="9">run_in_background=true · 后台执行</text>
<!-- ===== Timeline comparison ===== -->
<rect x="40" y="340" width="330" height="84" rx="6" fill="#fef2f2" stroke="#dc2626" stroke-width="1"/>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s12 同步阻塞</text>
<text x="205" y="360" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">s04 同步执行</text>
<rect x="60" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">思考</text>
<text x="100" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM 调用</text>
<rect x="145" y="370" width="160" height="14" rx="3" fill="#fecaca" stroke="#dc2626" stroke-width="1"/>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle">等 bash 3 分钟...</text>
<text x="225" y="381" fill="#991b1b" font-size="8" text-anchor="middle"> bash 返回</text>
<rect x="310" y="370" width="40" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">继续</text>
<text x="60" y="410" fill="#991b1b" font-size="9">总耗时 ~3minAgent 空 etc. 等了 3 分钟</text>
<text x="330" y="381" fill="#1e40af" font-size="7" text-anchor="middle">下一轮</text>
<text x="60" y="410" fill="#991b1b" font-size="9">命令结束后才能继续</text>
<rect x="390" y="340" width="330" height="84" rx="6" fill="#f0fdf4" stroke="#16a34a" stroke-width="1"/>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s13 后台执行</text>
<text x="555" y="360" fill="#166534" font-size="10" font-weight="700" text-anchor="middle">s11 后台执行</text>
<rect x="410" y="370" width="80" height="14" rx="3" fill="#dbeafe" stroke="#2563eb" stroke-width="1"/>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">思考</text>
<text x="450" y="381" fill="#1e40af" font-size="8" text-anchor="middle">LLM 调用</text>
<rect x="495" y="370" width="100" height="14" rx="3" fill="#dcfce7" stroke="#16a34a" stroke-width="1"/>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">继续做别的事</text>
<text x="545" y="381" fill="#166534" font-size="8" text-anchor="middle">继续其他工具</text>
<rect x="600" y="370" width="100" height="14" rx="3" fill="#fff7ed" stroke="#ea580c" stroke-width="1"/>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">通知: 结果来了</text>
<text x="410" y="410" fill="#166534" font-size="9">总耗时 ~3min但 Agent 没闲着</text>
<text x="650" y="381" fill="#ea580c" font-size="8" text-anchor="middle">后续轮次收集</text>
<text x="410" y="410" fill="#166534" font-size="9">bash 在后台线程运行</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,98 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 440" 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="#dc2626"/>
</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-red" 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="#dc2626"/>
</marker>
<linearGradient id="l1" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fde68a"/>
</linearGradient>
<linearGradient id="l2" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fed7aa"/><stop offset="100%" stop-color="#fdba74"/>
</linearGradient>
<linearGradient id="l3" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fecaca"/><stop offset="100%" stop-color="#fca5a5"/>
</linearGradient>
</defs>
<rect width="760" height="440" fill="#fafbfc" rx="8"/>
<!-- Title -->
<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">Error Recovery — try/except wrapping LLM calls, three recovery modes</text>
<!-- Legend -->
<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">s10 retained</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="158" y="66" fill="#d97706" font-size="10" font-weight="600">s11 new</text>
<!-- ===== s10 loop (compact) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="90" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="176" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt assembly</text>
<text x="176" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<line x1="221" y1="112" x2="239" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="242" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="292" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">compress + load</text>
<text x="292" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s08-s09)</text>
<line x1="342" y1="112" x2="360" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM (wrapped in try/except) -->
<rect x="363" y="86" width="80" height="52" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="2"/>
<text x="403" y="108" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<text x="403" y="122" fill="#dc2626" font-size="8" text-anchor="middle">try/except</text>
<line x1="443" y1="112" x2="461" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="464" y="86" width="110" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="519" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="519" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">bash · read · write</text>
<!-- Arrow: LLM → Recovery -->
<path d="M 403 138 L 403 178" fill="none" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<text x="415" y="164" fill="#dc2626" font-size="9">error</text>
<!-- ===== Recovery Section ===== -->
<rect x="20" y="182" width="720" height="22" rx="4" fill="#f1f5f9"/>
<text x="55" y="197" fill="#64748b" font-size="11" font-weight="600">Error Recovery (classify, recover, retry LLM)</text>
<!-- Layer 1: max_tokens -->
<rect x="40" y="210" width="680" height="48" rx="7" fill="url(#l1)" stroke="#d97706" stroke-width="1.5"/>
<text x="60" y="230" fill="#92400e" font-size="12" font-weight="600">Path 1</text>
<text x="112" y="230" fill="#92400e" font-size="11" font-weight="700">max_tokens</text>
<text x="200" y="230" fill="#92400e" font-size="11">Output truncated → escalate 8K→64K (once) / continuation prompt (max 3)</text>
<text x="200" y="246" fill="#b45309" font-size="9">Trigger: stop_reason == "max_tokens" · Cost: 0-1 API · Recover then continue</text>
<!-- Layer 2: prompt_too_long -->
<rect x="40" y="266" width="680" height="48" rx="7" fill="url(#l2)" stroke="#ea580c" stroke-width="1.5"/>
<text x="60" y="286" fill="#9a3412" font-size="12" font-weight="600">Path 2</text>
<text x="112" y="286" fill="#9a3412" font-size="11" font-weight="700">prompt_too_long</text>
<text x="230" y="286" fill="#9a3412" font-size="11">Context overflow → reactive compact → retry (one chance)</text>
<text x="200" y="302" fill="#c2410c" font-size="9">Trigger: API returns 413 · Cost: 1 API · Still over after compact → exit</text>
<!-- Layer 3: 429/529 -->
<rect x="40" y="322" width="680" height="48" rx="7" fill="url(#l3)" stroke="#dc2626" stroke-width="1.5"/>
<text x="60" y="342" fill="#991b1b" font-size="12" font-weight="600">Path 3</text>
<text x="112" y="342" fill="#991b1b" font-size="11" font-weight="700">429/529</text>
<text x="170" y="342" fill="#991b1b" font-size="11">Transient failure → exponential backoff + jitter (max 10) / 3×529 → switch model</text>
<text x="200" y="358" fill="#b91c1c" font-size="9">Trigger: RateLimitError / OverloadedError · Formula: min(500×2^n, 32s) + jitter</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="388" width="680" height="40" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="406" fill="#475569" font-size="10">Three most common recovery modes. CC has 13+ reason codes (image_error, aborted_streaming, etc.), each with dedicated handling.</text>
<text x="60" y="422" fill="#94a3b8" font-size="9">All paths after recovery → continue back to LLM · Normal flow: tool results → messages → loop</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,98 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 440" 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="#dc2626"/>
</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-red" 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="#dc2626"/>
</marker>
<linearGradient id="l1" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fde68a"/>
</linearGradient>
<linearGradient id="l2" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fed7aa"/><stop offset="100%" stop-color="#fdba74"/>
</linearGradient>
<linearGradient id="l3" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fecaca"/><stop offset="100%" stop-color="#fca5a5"/>
</linearGradient>
</defs>
<rect width="760" height="440" fill="#fafbfc" rx="8"/>
<!-- Title -->
<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">Error Recovery — try/except で LLM 呼び出しをラップ、3 つの復旧モード</text>
<!-- Legend -->
<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">s10 維持</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="158" y="66" fill="#d97706" font-size="10" font-weight="600">s11 新規</text>
<!-- ===== s10 loop (compact) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="90" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="176" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt assembly</text>
<text x="176" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<line x1="221" y1="112" x2="239" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="242" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="292" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">compress + load</text>
<text x="292" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s08-s09)</text>
<line x1="342" y1="112" x2="360" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM (wrapped in try/except) -->
<rect x="363" y="86" width="80" height="52" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="2"/>
<text x="403" y="108" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<text x="403" y="122" fill="#dc2626" font-size="8" text-anchor="middle">try/except</text>
<line x1="443" y1="112" x2="461" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="464" y="86" width="110" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="519" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="519" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">bash · read · write</text>
<!-- Arrow: LLM → Recovery -->
<path d="M 403 138 L 403 178" fill="none" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<text x="415" y="164" fill="#dc2626" font-size="9">エラー</text>
<!-- ===== Recovery Section ===== -->
<rect x="20" y="182" width="720" height="22" rx="4" fill="#f1f5f9"/>
<text x="55" y="197" fill="#64748b" font-size="11" font-weight="600">エラー復旧(分類処理、復旧後 LLM に戻りリトライ)</text>
<!-- Layer 1: max_tokens -->
<rect x="40" y="210" width="680" height="48" rx="7" fill="url(#l1)" stroke="#d97706" stroke-width="1.5"/>
<text x="60" y="230" fill="#92400e" font-size="12" font-weight="600">パス 1</text>
<text x="112" y="230" fill="#92400e" font-size="11" font-weight="700">max_tokens</text>
<text x="200" y="230" fill="#92400e" font-size="11">出力が途切れた → 8K→64K に拡張1 回)/ 続行プロンプト(最大 3 回)</text>
<text x="200" y="246" fill="#b45309" font-size="9">トリガー: stop_reason == "max_tokens" · コスト: 0-1 API · 復旧後 continue</text>
<!-- Layer 2: prompt_too_long -->
<rect x="40" y="266" width="680" height="48" rx="7" fill="url(#l2)" stroke="#ea580c" stroke-width="1.5"/>
<text x="60" y="286" fill="#9a3412" font-size="12" font-weight="600">パス 2</text>
<text x="112" y="286" fill="#9a3412" font-size="11" font-weight="700">prompt_too_long</text>
<text x="230" y="286" fill="#9a3412" font-size="11">コンテキスト超過 → reactive compact → リトライ1 回のみ)</text>
<text x="200" y="302" fill="#c2410c" font-size="9">トリガー: API が 413 返却 · コスト: 1 API · 圧縮後も超過 → 終了</text>
<!-- Layer 3: 429/529 -->
<rect x="40" y="322" width="680" height="48" rx="7" fill="url(#l3)" stroke="#dc2626" stroke-width="1.5"/>
<text x="60" y="342" fill="#991b1b" font-size="12" font-weight="600">パス 3</text>
<text x="112" y="342" fill="#991b1b" font-size="11" font-weight="700">429/529</text>
<text x="170" y="342" fill="#991b1b" font-size="11">一時障害 → 指数バックオフ + ジッター(最大 10 回)/ 3 回 529 → モデル切替</text>
<text x="200" y="358" fill="#b91c1c" font-size="9">トリガー: RateLimitError / OverloadedError · 式: min(500×2^n, 32s) + jitter</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="388" width="680" height="40" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="406" fill="#475569" font-size="10">最も一般的な 3 つの復旧モード。CC は実際に 13+ の reason code を持ちimage_error, aborted_streaming 等)、それぞれ専用の処理がある。</text>
<text x="60" y="422" fill="#94a3b8" font-size="9">全パス復旧後 → continue で LLM に戻る · 正常フロー: ツール結果 → messages → ループ</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -1,98 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 440" 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="#dc2626"/>
</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-red" 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="#dc2626"/>
</marker>
<linearGradient id="l1" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fde68a"/>
</linearGradient>
<linearGradient id="l2" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fed7aa"/><stop offset="100%" stop-color="#fdba74"/>
</linearGradient>
<linearGradient id="l3" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fecaca"/><stop offset="100%" stop-color="#fca5a5"/>
</linearGradient>
</defs>
<rect width="760" height="440" fill="#fafbfc" rx="8"/>
<!-- Title -->
<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">Error Recovery — try/except 包裹 LLM 调用,三种恢复模式</text>
<!-- Legend -->
<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">s10 保留</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="158" y="66" fill="#d97706" font-size="10" font-weight="600">s11 新增</text>
<!-- ===== s10 loop (compact) ===== -->
<rect x="30" y="92" width="80" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="70" y="116" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="110" y1="112" x2="128" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="131" y="86" width="90" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="176" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt assembly</text>
<text x="176" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<line x1="221" y1="112" x2="239" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="242" y="86" width="100" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="292" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">compress + load</text>
<text x="292" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">(s08-s09)</text>
<line x1="342" y1="112" x2="360" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM (wrapped in try/except) -->
<rect x="363" y="86" width="80" height="52" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="2"/>
<text x="403" y="108" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">LLM</text>
<text x="403" y="122" fill="#dc2626" font-size="8" text-anchor="middle">try/except</text>
<line x1="443" y1="112" x2="461" y2="112" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="464" y="86" width="110" height="52" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="519" y="108" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">TOOL_HANDLERS</text>
<text x="519" y="122" fill="#94a3b8" font-size="8" text-anchor="middle">bash · read · write</text>
<!-- Arrow: LLM → Recovery -->
<path d="M 403 138 L 403 178" fill="none" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<text x="415" y="164" fill="#dc2626" font-size="9">报错</text>
<!-- ===== Recovery Section ===== -->
<rect x="20" y="182" width="720" height="22" rx="4" fill="#f1f5f9"/>
<text x="55" y="197" fill="#64748b" font-size="11" font-weight="600">错误恢复(分类处理,恢复后回到 LLM 重试)</text>
<!-- Layer 1: max_tokens -->
<rect x="40" y="210" width="680" height="48" rx="7" fill="url(#l1)" stroke="#d97706" stroke-width="1.5"/>
<text x="60" y="230" fill="#92400e" font-size="12" font-weight="600">路径 1</text>
<text x="112" y="230" fill="#92400e" font-size="11" font-weight="700">max_tokens</text>
<text x="200" y="230" fill="#92400e" font-size="11">输出被截断 → 升级 8K→64K一次/ 续写提示(最多 3 次)</text>
<text x="200" y="246" fill="#b45309" font-size="9">触发: stop_reason == "max_tokens" · 代价: 0-1 API · 恢复后 continue</text>
<!-- Layer 2: prompt_too_long -->
<rect x="40" y="266" width="680" height="48" rx="7" fill="url(#l2)" stroke="#ea580c" stroke-width="1.5"/>
<text x="60" y="286" fill="#9a3412" font-size="12" font-weight="600">路径 2</text>
<text x="112" y="286" fill="#9a3412" font-size="11" font-weight="700">prompt_too_long</text>
<text x="230" y="286" fill="#9a3412" font-size="11">上下文超限 → reactive compact → 重试(一次机会)</text>
<text x="200" y="302" fill="#c2410c" font-size="9">触发: API 返回 413 · 代价: 1 API · 压缩过还是超 → 退出</text>
<!-- Layer 3: 429/529 -->
<rect x="40" y="322" width="680" height="48" rx="7" fill="url(#l3)" stroke="#dc2626" stroke-width="1.5"/>
<text x="60" y="342" fill="#991b1b" font-size="12" font-weight="600">路径 3</text>
<text x="112" y="342" fill="#991b1b" font-size="11" font-weight="700">429/529</text>
<text x="170" y="342" fill="#991b1b" font-size="11">临时故障 → 指数退避 + 抖动(最多 10 次)/ 3 次 529 → 切换模型</text>
<text x="200" y="358" fill="#b91c1c" font-size="9">触发: RateLimitError / OverloadedError · 公式: min(500×2^n, 32s) + jitter</text>
<!-- ===== Bottom notes ===== -->
<rect x="40" y="388" width="680" height="40" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="406" fill="#475569" font-size="10">三种最常见的恢复模式。CC 实际有 13+ reason codeimage_error、aborted_streaming 等),各有专门处理。</text>
<text x="60" y="422" fill="#94a3b8" font-size="9">所有路径恢复后 → continue 回到 LLM · 正常流程: 工具结果 → messages → 循环</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -20,49 +20,49 @@
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f8fafc" stroke="#94a3b8" stroke-width="1"/>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">s10-s13 retained</text>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">S04 tools + hooks</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">s14 new</text>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">S12 new</text>
<!-- ===== Row 1: Full Agent Loop Chain ===== -->
<!-- consume_cron_queue (s14 new, indigo) -->
<!-- consume_cron_queue (S12 new, indigo) -->
<rect x="30" y="100" width="95" height="48" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="77" y="120" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">consume</text>
<text x="77" y="134" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">s14 injection</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">S12 injection</text>
<line x1="125" y1="124" x2="143" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- messages (s10) -->
<!-- messages base instructions -->
<rect x="146" y="100" width="80" height="48" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="186" y="128" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="226" y1="124" x2="244" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- prompt + cache (s10) -->
<!-- system prompt base instructions -->
<rect x="247" y="94" width="115" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">assemble_system_prompt</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">SYSTEM</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">base instructions</text>
<line x1="362" y1="124" x2="380" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM call (s11 retry) -->
<!-- LLM call -->
<rect x="383" y="94" width="100" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">with_retry</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">client.messages.create</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="483" y1="124" x2="501" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="504" y="88" width="220" height="72" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="614" y="106" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="519" y="122" fill="#2563eb" font-size="8">fastsync (bash, read, write)</text>
<text x="519" y="134" fill="#ea580c" font-size="8">slow → background thread (s13)</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (s14)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">task → create, list, claim, complete (s12)</text>
<text x="519" y="122" fill="#2563eb" font-size="8">base → bash, read, write, edit, glob</text>
<text x="519" y="134" fill="#ea580c" font-size="8">PreToolUse → permission + log</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (S12)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">PostToolUse → output check</text>
<!-- Loop back arrow -->
<path d="M 724 124 L 748 124 L 748 170 L 77 170 L 77 148" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
@@ -71,10 +71,10 @@
<!-- ===== Row 2: Cron Scheduler Thread (indigo) ===== -->
<rect x="30" y="206" width="250" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="155" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">cron_scheduler_loop (daemon thread)</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">time.sleep(1) → cron_matches(job.cron, now)</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">match → cron_queue.append(job)</text>
<text x="48" y="272" fill="#6b7280" font-size="8">minute_marker prevents double-fire per minute</text>
<text x="48" y="286" fill="#6b7280" font-size="8">one-shot jobs auto-delete after firing</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">wait(1s) → poll_due_jobs(datetime.now())</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">match → persist state → enqueue job</text>
<text x="48" y="272" fill="#6b7280" font-size="8">last_fired prevents duplicate enqueue per minute</text>
<text x="48" y="286" fill="#6b7280" font-size="8">one-shot is removed after the model accepts the prompt</text>
<!-- Arrow: scheduler → cron_queue -->
<path d="M 155 296 L 155 330" fill="none" stroke="#4f46e5" stroke-width="1.5" marker-end="url(#arrow-indigo)"/>
@@ -82,16 +82,16 @@
<!-- cron_queue (indigo) -->
<rect x="60" y="333" width="200" height="38" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="160" y="352" fill="#312e81" font-size="10" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock · scheduler writes · loop reads</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock · scheduler writes · processor delivers</text>
<!-- Arrow: cron_queue → consume_cron_queue (connects to top row) -->
<path d="M 77 333 L 77 318 L 18 318 L 18 124 L 30 124" fill="none" stroke="#4f46e5" stroke-width="2" marker-end="url(#arrow-indigo)"/>
<text x="95" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">next agent_loop consumes</text>
<text x="95" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">idle Agent receives it</text>
<!-- ===== Row 2 Right: CronJob + Storage ===== -->
<rect x="320" y="206" width="410" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="525" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">CronJob + Persistence</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob dataclass:</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob core fields:</text>
<text x="455" y="244" fill="#6b7280" font-size="8">id, cron, prompt, recurring, durable</text>
<text x="338" y="260" fill="#4f46e5" font-size="9" font-weight="600">Durable → .scheduled_tasks.json</text>
<text x="560" y="260" fill="#6b7280" font-size="8">restored via load_durable_jobs after restart</text>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -20,49 +20,49 @@
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f8fafc" stroke="#94a3b8" stroke-width="1"/>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">s10-s13 維持</text>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">S04 tools + hooks</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">s14 新規</text>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">S12 新規</text>
<!-- ===== Row 1: Full Agent Loop Chain ===== -->
<!-- consume_cron_queue (s14 new, indigo) -->
<!-- consume_cron_queue (S12 new, indigo) -->
<rect x="30" y="100" width="95" height="48" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="77" y="120" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">consume</text>
<text x="77" y="134" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">s14 注入点</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">S12 注入点</text>
<line x1="125" y1="124" x2="143" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- messages (s10) -->
<!-- messages base instructions -->
<rect x="146" y="100" width="80" height="48" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="186" y="128" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="226" y1="124" x2="244" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- prompt + cache (s10) -->
<!-- system prompt base instructions -->
<rect x="247" y="94" width="115" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">assemble_system_prompt</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">SYSTEM</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">base instructions</text>
<line x1="362" y1="124" x2="380" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM call (s11 retry) -->
<!-- LLM call -->
<rect x="383" y="94" width="100" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">with_retry</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">client.messages.create</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="483" y1="124" x2="501" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="504" y="88" width="220" height="72" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="614" y="106" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="519" y="122" fill="#2563eb" font-size="8">fastsync (bash, read, write)</text>
<text x="519" y="134" fill="#ea580c" font-size="8">slow → background thread (s13)</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (s14)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">task → create, list, claim, complete (s12)</text>
<text x="519" y="122" fill="#2563eb" font-size="8">base → bash, read, write, edit, glob</text>
<text x="519" y="134" fill="#ea580c" font-size="8">PreToolUse → permission + log</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (S12)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">PostToolUse → output check</text>
<!-- Loop back arrow -->
<path d="M 724 124 L 748 124 L 748 170 L 77 170 L 77 148" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
@@ -71,10 +71,10 @@
<!-- ===== Row 2: Cron Scheduler Thread (indigo) ===== -->
<rect x="30" y="206" width="250" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="155" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">cron_scheduler_loop (daemon スレッド)</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">time.sleep(1) → cron_matches(job.cron, now)</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">マッチ → cron_queue.append(job)</text>
<text x="48" y="272" fill="#6b7280" font-size="8">minute_marker で同一分の重複発火を防止</text>
<text x="48" y="286" fill="#6b7280" font-size="8">一度きりのタスクは発火後自動削除</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">wait(1s) → poll_due_jobs(datetime.now())</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">マッチ → 状態を保存 → queue へ追加</text>
<text x="48" y="272" fill="#6b7280" font-size="8">last_fired で同一分の重複投入を防止</text>
<text x="48" y="286" fill="#6b7280" font-size="8">model が prompt を受け取った後に削除</text>
<!-- Arrow: scheduler → cron_queue -->
<path d="M 155 296 L 155 330" fill="none" stroke="#4f46e5" stroke-width="1.5" marker-end="url(#arrow-indigo)"/>
@@ -82,16 +82,16 @@
<!-- cron_queue (indigo) -->
<rect x="60" y="333" width="200" height="38" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="160" y="352" fill="#312e81" font-size="10" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock · スケジューラ書込 · loop 読込</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock · scheduler 書込 · processor 配信</text>
<!-- Arrow: cron_queue → consume_cron_queue (connects to top row) -->
<path d="M 77 333 L 77 318 L 18 318 L 18 124 L 30 124" fill="none" stroke="#4f46e5" stroke-width="2" marker-end="url(#arrow-indigo)"/>
<text x="80" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">次の agent_loop が消費</text>
<text x="80" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">Agent idle 時に配信</text>
<!-- ===== Row 2 Right: CronJob + Storage ===== -->
<rect x="320" y="206" width="410" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="525" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">CronJob + 永続化</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob dataclass:</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob core fields:</text>
<text x="455" y="244" fill="#6b7280" font-size="8">id, cron, prompt, recurring, durable</text>
<text x="338" y="260" fill="#4f46e5" font-size="9" font-weight="600">Durable → .scheduled_tasks.json</text>
<text x="560" y="260" fill="#6b7280" font-size="8">再起動後 load_durable_jobs で復元</text>

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -20,49 +20,49 @@
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f8fafc" stroke="#94a3b8" stroke-width="1"/>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">s10-s13 保留</text>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">S04 工具与 Hooks</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">s14 新增</text>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">S12 新增</text>
<!-- ===== Row 1: Full Agent Loop Chain ===== -->
<!-- consume_cron_queue (s14 new, indigo) -->
<!-- consume_cron_queue (S12 new, indigo) -->
<rect x="30" y="100" width="95" height="48" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="77" y="120" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">consume</text>
<text x="77" y="134" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">s14 注入点</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">S12 注入点</text>
<line x1="125" y1="124" x2="143" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- messages (s10) -->
<!-- messages 基础指令 -->
<rect x="146" y="100" width="80" height="48" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="186" y="128" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="226" y1="124" x2="244" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- prompt + cache (s10) -->
<!-- system prompt 基础指令 -->
<rect x="247" y="94" width="115" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt + cache</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">assemble_system_prompt</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s10)</text>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">SYSTEM</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">基础指令</text>
<line x1="362" y1="124" x2="380" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM call (s11 retry) -->
<!-- LLM call -->
<rect x="383" y="94" width="100" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM (try/except)</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">with_retry</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">(s11)</text>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">client.messages.create</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="483" y1="124" x2="501" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="504" y="88" width="220" height="72" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="614" y="106" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="519" y="122" fill="#2563eb" font-size="8">fast → sync (bash, read, write)</text>
<text x="519" y="134" fill="#ea580c" font-size="8">slow → background thread (s13)</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (s14)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">task → create, list, claim, complete (s12)</text>
<text x="519" y="122" fill="#2563eb" font-size="8">基础工具 → bash, read, write, edit, glob</text>
<text x="519" y="134" fill="#ea580c" font-size="8">PreToolUse → permission + log</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (S12)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">PostToolUse → output check</text>
<!-- Loop back arrow -->
<path d="M 724 124 L 748 124 L 748 170 L 77 170 L 77 148" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
@@ -71,10 +71,10 @@
<!-- ===== Row 2: Cron Scheduler Thread (indigo) ===== -->
<rect x="30" y="206" width="250" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="155" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">cron_scheduler_loop独立 daemon 线程)</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">time.sleep(1) → cron_matches(job.cron, now)</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">匹配 → cron_queue.append(job)</text>
<text x="48" y="272" fill="#6b7280" font-size="8">minute_marker 防同分钟重复触发</text>
<text x="48" y="286" fill="#6b7280" font-size="8">一次性任务触发后自动删除</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">wait(1s) → poll_due_jobs(datetime.now())</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">匹配 → 持久化状态 → 加入队列</text>
<text x="48" y="272" fill="#6b7280" font-size="8">last_fired 防止同一分钟重复入队</text>
<text x="48" y="286" fill="#6b7280" font-size="8">模型接收 prompt 后删除一次性任务</text>
<!-- Arrow: scheduler → cron_queue -->
<path d="M 155 296 L 155 330" fill="none" stroke="#4f46e5" stroke-width="1.5" marker-end="url(#arrow-indigo)"/>
@@ -82,16 +82,16 @@
<!-- cron_queue (indigo) -->
<rect x="60" y="333" width="200" height="38" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="160" y="352" fill="#312e81" font-size="10" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock 保护 · 调度线程写 · agent_loop 读</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock 保护 · scheduler 写 · processor 交付</text>
<!-- Arrow: cron_queue → consume_cron_queue (connects to top row) -->
<path d="M 77 333 L 77 318 L 18 318 L 18 124 L 30 124" fill="none" stroke="#4f46e5" stroke-width="2" marker-end="url(#arrow-indigo)"/>
<text x="72" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">下次 agent_loop 消费</text>
<text x="72" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">Agent 空闲后交付</text>
<!-- ===== Row 2 Right: CronJob + Storage ===== -->
<rect x="320" y="206" width="410" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="525" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">CronJob + 持久化</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob dataclass:</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob 核心字段:</text>
<text x="455" y="244" fill="#6b7280" font-size="8">id, cron, prompt, recurring, durable</text>
<text x="338" y="260" fill="#4f46e5" font-size="9" font-weight="600">Durable → .scheduled_tasks.json</text>
<text x="560" y="260" fill="#6b7280" font-size="8">重启后 load_durable_jobs 恢复</text>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -32,7 +32,7 @@
<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/remove · plan review</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)"/>
@@ -93,7 +93,7 @@
<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">Default: repository WORKDIR</text>
<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>

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -32,7 +32,7 @@
<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>
<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)"/>
@@ -93,7 +93,7 @@
<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">デフォルト:リポジトリ WORKDIR</text>
<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>

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -32,7 +32,7 @@
<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>
<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)"/>
@@ -93,7 +93,7 @@
<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">默认:仓库 WORKDIR</text>
<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>

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -43,7 +43,7 @@
<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">bash · read · write · task(4) · spawn · send · inbox</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"/>
@@ -73,7 +73,7 @@
<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">Plain message (msg_type="message")</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"/>
@@ -93,7 +93,7 @@
<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 is a plain message, not a protocol; submit_plan is the protocol entry point (creates ProtocolState on teammate side)</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"/>
@@ -129,7 +129,7 @@
<!-- 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 is a plain message (msg_type="message") sent by lead to prompt a plan submission.</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 -->

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -43,7 +43,7 @@
<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="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"/>
@@ -73,7 +73,7 @@
<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>
<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"/>
@@ -93,7 +93,7 @@
<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>
<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"/>
@@ -129,7 +129,7 @@
<!-- 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="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 -->

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -43,7 +43,7 @@
<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="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"/>
@@ -73,7 +73,7 @@
<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>
<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"/>
@@ -93,7 +93,7 @@
<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>
<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"/>
@@ -129,7 +129,7 @@
<!-- 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="100" y="588" fill="#475569" font-size="9">request_plan 发送 plan_requestsubmit_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 -->

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -19,15 +19,15 @@
<!-- Title -->
<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">MCP Plugin — Standard Protocol + External Tool Integration + Tool Pool Assembly</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">MCP Tools — Discovery + Dynamic Tool Pool</text>
<!-- Legend -->
<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 Preserved</text>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 Base Loop</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="178" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 New</text>
<text x="178" y="66" fill="#dc2626" font-size="10" font-weight="600">s14 New</text>
<!-- ===== Row 1: Lead Loop (s15 preserved) ===== -->
<!-- ===== Row 1: Lead Loop (s13 preserved) ===== -->
<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>
@@ -49,18 +49,18 @@
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH (Lead 16 tools)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · host cleanup</text>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH (dynamic pool)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · edit · glob</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">connect_mcp</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">mcp__server__tool from connected servers</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + dynamic mcp__server__tool tools</text>
<!-- Loop back -->
<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: MCP Architecture (s16 new) ===== -->
<!-- ===== Row 2: MCP Architecture (s14 new) ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP Architecture (s16 new: standard protocol + dynamic external tools)</text>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP Architecture (s14 new: standard protocol + dynamic external tools)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
@@ -73,7 +73,7 @@
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool assembles builtin + mcp</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">handler → call_tool("search", args)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
@@ -93,7 +93,7 @@
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">Any language, just needs stdio JSON-RPC</text>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">This lesson uses in-process server stand-ins</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
@@ -102,11 +102,11 @@
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: atomic claims + task worktrees + protocols</text>
<text x="70" y="418" fill="#475569" font-size="10">s04: base tools + hooks + permission</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic tools (Lead 16)</text>
<text x="440" y="418" fill="#475569" font-size="10">s14: MCP + dynamic tool pool</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">Next: s17 combines tools, permissions, teams, worktrees, MCP, and more into one while True loop.</text>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">Next: s15 combines tools, permissions, teams, worktrees, MCP, and more into one while True loop.</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -19,13 +19,13 @@
<!-- Title -->
<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">MCP Plugin — 標準プロトコル + 外部ツール接続 + ツールプール組み立て</text>
<text x="380" y="28" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">MCP Tools — Tool Discovery + Dynamic Tool Pool</text>
<!-- Legend -->
<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>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 Base Loop</text>
<rect x="130" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="148" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 新規</text>
<text x="148" y="66" fill="#dc2626" font-size="10" font-weight="600">s14 新規</text>
<!-- ===== Row 1: Lead Loop ===== -->
<rect x="20" y="90" width="70" height="40" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="1.5"/>
@@ -49,10 +49,10 @@
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCHLead 16 tools</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · host cleanup</text>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCHdynamic pool</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · edit · glob</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">connect_mcp</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">接続済み server の mcp__server__tool</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + 動的 mcp__server__tool ツール</text>
<!-- Loop back -->
@@ -60,7 +60,7 @@
<!-- ===== Row 2: MCP Architecture ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP アーキテクチャs16 新規:標準プロトコル + 外部ツール動的統合)</text>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP アーキテクチャs14 新規:標準プロトコル + 外部ツール動的統合)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
@@ -73,7 +73,7 @@
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool builtin + mcp 組み立て</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">handler → call_tool("search", args)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
@@ -93,7 +93,7 @@
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">任意言語実装、stdio JSON-RPC のみ必要</text>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">本章は in-process mock server を使用</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
@@ -102,11 +102,11 @@
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: atomic claim + task worktree + protocols</text>
<text x="70" y="418" fill="#475569" font-size="10">s04: base tools + hooks + permission</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic toolsLead 16</text>
<text x="440" y="418" fill="#475569" font-size="10">s14: MCP + dynamic tool pool</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">次の s17tools、permissions、teams、worktree、MCP などを 1 つの while True ループに統合。</text>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">次の s15tools、permissions、teams、worktree、MCP などを 1 つの while True ループに統合。</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -19,15 +19,15 @@
<!-- Title -->
<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">MCP Plugin — 标准协议 + 外部工具接入 + 工具池组装</text>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">MCP Tools — 工具发现 + 动态工具池</text>
<!-- Legend -->
<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>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s04 基础循环</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="158" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 新增</text>
<text x="158" y="66" fill="#dc2626" font-size="10" font-weight="600">s14 新增</text>
<!-- ===== Row 1: Lead Loop (s15 preserved) ===== -->
<!-- ===== Row 1: Lead Loop (s13 preserved) ===== -->
<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>
@@ -49,18 +49,18 @@
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH (Lead 16 tools)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · host cleanup</text>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH(动态工具池)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · edit · glob</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">connect_mcp</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">已连接 server 的 mcp__server__tool</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + 动态 mcp__server__tool 工具</text>
<!-- Loop back -->
<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: MCP Architecture (s16 new) ===== -->
<!-- ===== Row 2: MCP Architecture (s14 new) ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP 架构s16 新增:标准协议 + 外部工具动态接入)</text>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP 架构s14 新增:标准协议 + 外部工具动态接入)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
@@ -73,7 +73,7 @@
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool 组装 builtin + mcp</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">handler → call_tool("search", args)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
@@ -93,7 +93,7 @@
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">任意语言实现,只需 stdio JSON-RPC</text>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">本章使用进程内模拟 server</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
@@ -102,11 +102,11 @@
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: 原子认领 + 任务 worktree + 协议</text>
<text x="70" y="418" fill="#475569" font-size="10">s04: 基础工具 + Hooks + Permission</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic tools (Lead 16)</text>
<text x="440" y="418" fill="#475569" font-size="10">s14: MCP + dynamic tool pool</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">下一章 s17把工具、权限、团队、worktree、MCP 等机制合回同一个 while True 循环。</text>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">下一章 s15把工具、权限、团队、worktree、MCP 等机制合回同一个 while True 循环。</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -20,7 +20,7 @@
<rect width="920" height="620" rx="8" fill="#fafbfc"/>
<rect x="0" y="0" width="920" height="46" rx="8" fill="url(#header)"/>
<rect x="0" y="38" width="920" height="8" fill="url(#header)"/>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s17 Integrated Harness — Many Mechanisms, One Loop</text>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s15 Integrated Harness — Many Mechanisms, One Loop</text>
<rect x="40" y="76" width="840" height="212" rx="8" fill="#eef2ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="460" y="101" text-anchor="middle" fill="#1e3a8a" font-size="13" font-weight="700">Core Agent Loop</text>
<rect x="70" y="128" width="110" height="48" rx="7" fill="#fff" stroke="#2563eb" stroke-width="1.4"/>
@@ -49,32 +49,32 @@
<text x="135" y="341" text-anchor="middle" fill="#065f46" font-size="11" font-weight="700">Context &amp; Knowledge</text>
<text x="58" y="362" fill="#047857" font-size="9">s07 skills + load_skill</text>
<text x="58" y="377" fill="#047857" font-size="9">s09 memory selection</text>
<text x="58" y="392" fill="#047857" font-size="9">s10 prompt sections</text>
<text x="58" y="392" fill="#047857" font-size="9">assembled system prompt</text>
<text x="58" y="407" fill="#047857" font-size="9">s08 compact pipeline</text>
<path d="M 230 350 L 282 186" fill="none" stroke="#059669" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
<rect x="260" y="318" width="190" height="104" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="1.4"/>
<text x="355" y="341" text-anchor="middle" fill="#9a3412" font-size="11" font-weight="700">Governance</text>
<text x="278" y="362" fill="#c2410c" font-size="9">s03 permission</text>
<text x="278" y="377" fill="#c2410c" font-size="9">s04 hooks</text>
<text x="278" y="392" fill="#c2410c" font-size="9">s11 retry / fallback</text>
<text x="278" y="392" fill="#c2410c" font-size="9">model retry / fallback</text>
<text x="278" y="407" fill="#c2410c" font-size="9">Stop hooks</text>
<path d="M 450 350 L 592 186" fill="none" stroke="#ea580c" stroke-width="1.3" marker-end="url(#arrow-orange)" stroke-dasharray="5,3"/>
<rect x="480" y="318" width="190" height="104" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4"/>
<text x="575" y="341" text-anchor="middle" fill="#5b21b6" font-size="11" font-weight="700">Durable Work</text>
<text x="498" y="362" fill="#6d28d9" font-size="9">s05 todo_write</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s12 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s13 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s14 cron scheduler</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s10 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s11 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s12 cron scheduler</text>
<path d="M 575 318 L 575 188" fill="none" stroke="#7c3aed" stroke-width="1.3" marker-end="url(#arrow-purple)" stroke-dasharray="5,3"/>
<rect x="700" y="318" width="180" height="104" rx="8" fill="#f0fdfa" stroke="#0d9488" stroke-width="1.4"/>
<text x="790" y="341" text-anchor="middle" fill="#0f766e" font-size="11" font-weight="700">Teams &amp; Plugins</text>
<text x="718" y="362" fill="#0f766e" font-size="9">s06 subagent</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s15 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s15 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s16 MCP tools</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s13 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s13 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s14 MCP tools</text>
<path d="M 790 318 L 790 188" fill="none" stroke="#0d9488" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
<rect x="70" y="462" width="780" height="112" rx="8" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.2"/>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 27 builtins + dynamic mcp__server__tool</text>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 25 builtins + dynamic mcp__server__tool</text>
<text x="95" y="512" fill="#334155" font-size="9">file/shell: bash · read · write · edit · glob</text>
<text x="95" y="530" fill="#334155" font-size="9">single-agent: todo_write · task · load_skill · compact</text>
<text x="95" y="548" fill="#334155" font-size="9">durable work: task tools · cron tools</text>

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -20,7 +20,7 @@
<rect width="920" height="620" rx="8" fill="#fafbfc"/>
<rect x="0" y="0" width="920" height="46" rx="8" fill="url(#header)"/>
<rect x="0" y="38" width="920" height="8" fill="url(#header)"/>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s17 Integrated Harness — 多くの仕組みを 1 つのループへ</text>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s15 Integrated Harness — 多くの仕組みを 1 つのループへ</text>
<rect x="40" y="76" width="840" height="212" rx="8" fill="#eef2ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="460" y="101" text-anchor="middle" fill="#1e3a8a" font-size="13" font-weight="700">Core Agent Loop</text>
<rect x="70" y="128" width="110" height="48" rx="7" fill="#fff" stroke="#2563eb" stroke-width="1.4"/>
@@ -49,32 +49,32 @@
<text x="135" y="341" text-anchor="middle" fill="#065f46" font-size="11" font-weight="700">Context / Knowledge</text>
<text x="58" y="362" fill="#047857" font-size="9">s07 skills + load_skill</text>
<text x="58" y="377" fill="#047857" font-size="9">s09 memory selection</text>
<text x="58" y="392" fill="#047857" font-size="9">s10 prompt sections</text>
<text x="58" y="392" fill="#047857" font-size="9">assembled system prompt</text>
<text x="58" y="407" fill="#047857" font-size="9">s08 compact pipeline</text>
<path d="M 230 350 L 282 186" fill="none" stroke="#059669" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
<rect x="260" y="318" width="190" height="104" rx="8" fill="#fff7ed" stroke="#ea580c" stroke-width="1.4"/>
<text x="355" y="341" text-anchor="middle" fill="#9a3412" font-size="11" font-weight="700">Governance</text>
<text x="278" y="362" fill="#c2410c" font-size="9">s03 permission</text>
<text x="278" y="377" fill="#c2410c" font-size="9">s04 hooks</text>
<text x="278" y="392" fill="#c2410c" font-size="9">s11 retry / fallback</text>
<text x="278" y="392" fill="#c2410c" font-size="9">model retry / fallback</text>
<text x="278" y="407" fill="#c2410c" font-size="9">Stop hooks</text>
<path d="M 450 350 L 592 186" fill="none" stroke="#ea580c" stroke-width="1.3" marker-end="url(#arrow-orange)" stroke-dasharray="5,3"/>
<rect x="480" y="318" width="190" height="104" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4"/>
<text x="575" y="341" text-anchor="middle" fill="#5b21b6" font-size="11" font-weight="700">Durable Work</text>
<text x="498" y="362" fill="#6d28d9" font-size="9">s05 todo_write</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s12 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s13 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s14 cron scheduler</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s10 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s11 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s12 cron scheduler</text>
<path d="M 575 318 L 575 188" fill="none" stroke="#7c3aed" stroke-width="1.3" marker-end="url(#arrow-purple)" stroke-dasharray="5,3"/>
<rect x="700" y="318" width="180" height="104" rx="8" fill="#f0fdfa" stroke="#0d9488" stroke-width="1.4"/>
<text x="790" y="341" text-anchor="middle" fill="#0f766e" font-size="11" font-weight="700">Teams / Plugins</text>
<text x="718" y="362" fill="#0f766e" font-size="9">s06 subagent</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s15 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s15 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s16 MCP tools</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s13 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s13 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s14 MCP tools</text>
<path d="M 790 318 L 790 188" fill="none" stroke="#0d9488" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
<rect x="70" y="462" width="780" height="112" rx="8" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.2"/>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 27 builtins + dynamic mcp__server__tool</text>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 25 builtins + dynamic mcp__server__tool</text>
<text x="95" y="512" fill="#334155" font-size="9">file/shell: bash · read · write · edit · glob</text>
<text x="95" y="530" fill="#334155" font-size="9">single-agent: todo_write · task · load_skill · compact</text>
<text x="95" y="548" fill="#334155" font-size="9">durable work: task tools · cron tools</text>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -21,7 +21,7 @@
<rect width="920" height="620" rx="8" fill="#fafbfc"/>
<rect x="0" y="0" width="920" height="46" rx="8" fill="url(#header)"/>
<rect x="0" y="38" width="920" height="8" fill="url(#header)"/>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s17 Agent Harness 集成 — 多种机制,一个循环</text>
<text x="460" y="29" text-anchor="middle" fill="#fff" font-size="17" font-weight="700">s15 Agent Harness 集成 — 多种机制,一个循环</text>
<!-- Main loop band -->
<rect x="40" y="76" width="840" height="212" rx="8" fill="#eef2ff" stroke="#2563eb" stroke-width="1.8"/>
@@ -64,7 +64,7 @@
<text x="135" y="341" text-anchor="middle" fill="#065f46" font-size="11" font-weight="700">上下文与知识</text>
<text x="58" y="362" fill="#047857" font-size="9">s07 skills catalog + load_skill</text>
<text x="58" y="377" fill="#047857" font-size="9">s09 memory selection</text>
<text x="58" y="392" fill="#047857" font-size="9">s10 prompt sections</text>
<text x="58" y="392" fill="#047857" font-size="9">组合后的 system prompt</text>
<text x="58" y="407" fill="#047857" font-size="9">s08 compact pipeline</text>
<path d="M 230 350 L 282 186" fill="none" stroke="#059669" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
@@ -72,29 +72,29 @@
<text x="355" y="341" text-anchor="middle" fill="#9a3412" font-size="11" font-weight="700">治理与扩展点</text>
<text x="278" y="362" fill="#c2410c" font-size="9">s03 permission</text>
<text x="278" y="377" fill="#c2410c" font-size="9">s04 hooks</text>
<text x="278" y="392" fill="#c2410c" font-size="9">s11 retry / fallback</text>
<text x="278" y="392" fill="#c2410c" font-size="9">model retry / fallback</text>
<text x="278" y="407" fill="#c2410c" font-size="9">Stop hooks</text>
<path d="M 450 350 L 592 186" fill="none" stroke="#ea580c" stroke-width="1.3" marker-end="url(#arrow-orange)" stroke-dasharray="5,3"/>
<rect x="480" y="318" width="190" height="104" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4"/>
<text x="575" y="341" text-anchor="middle" fill="#5b21b6" font-size="11" font-weight="700">持久工作</text>
<text x="498" y="362" fill="#6d28d9" font-size="9">s05 todo_write</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s12 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s13 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s14 cron scheduler</text>
<text x="498" y="377" fill="#6d28d9" font-size="9">s10 task graph</text>
<text x="498" y="392" fill="#6d28d9" font-size="9">s11 background</text>
<text x="498" y="407" fill="#6d28d9" font-size="9">s12 cron scheduler</text>
<path d="M 575 318 L 575 188" fill="none" stroke="#7c3aed" stroke-width="1.3" marker-end="url(#arrow-purple)" stroke-dasharray="5,3"/>
<rect x="700" y="318" width="180" height="104" rx="8" fill="#f0fdfa" stroke="#0d9488" stroke-width="1.4"/>
<text x="790" y="341" text-anchor="middle" fill="#0f766e" font-size="11" font-weight="700">团队与插件</text>
<text x="718" y="362" fill="#0f766e" font-size="9">s06 subagent</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s15 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s15 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s16 MCP tools</text>
<text x="718" y="377" fill="#0f766e" font-size="9">s13 teams + task protocols</text>
<text x="718" y="392" fill="#0f766e" font-size="9">s13 task-bound worktrees</text>
<text x="718" y="407" fill="#0f766e" font-size="9">s14 MCP tools</text>
<path d="M 790 318 L 790 188" fill="none" stroke="#0d9488" stroke-width="1.3" marker-end="url(#arrow-green)" stroke-dasharray="5,3"/>
<!-- Tool pool -->
<rect x="70" y="462" width="780" height="112" rx="8" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.2"/>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 27 builtins + dynamic mcp__server__tool</text>
<text x="460" y="487" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="700">TOOL POOL: 25 builtins + dynamic mcp__server__tool</text>
<text x="95" y="512" fill="#334155" font-size="9">file/shell: bash · read · write · edit · glob</text>
<text x="95" y="530" fill="#334155" font-size="9">single-agent: todo_write · task · load_skill · compact</text>
<text x="95" y="548" fill="#334155" font-size="9">durable work: create/list/get/claim/complete_task · schedule/list/cancel_cron</text>

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -23,8 +23,6 @@ import s14Annotations from "@/data/annotations/s14.json";
import s15Annotations from "@/data/annotations/s15.json";
import s16Annotations from "@/data/annotations/s16.json";
import s17Annotations from "@/data/annotations/s17.json";
import s18Annotations from "@/data/annotations/s18.json";
import s19Annotations from "@/data/annotations/s19.json";
interface Decision {
id: string;
@@ -58,8 +56,6 @@ const ANNOTATIONS: Record<string, AnnotationFile> = {
s15: s15Annotations as AnnotationFile,
s16: s16Annotations as AnnotationFile,
s17: s17Annotations as AnnotationFile,
s18: s18Annotations as AnnotationFile,
s19: s19Annotations as AnnotationFile,
};
interface DesignDecisionsProps {

View File

@@ -26,8 +26,6 @@ const scenarioModules: Record<string, () => Promise<{ default: Scenario }>> = {
s15: () => import("@/data/scenarios/s15.json") as Promise<{ default: Scenario }>,
s16: () => import("@/data/scenarios/s16.json") as Promise<{ default: Scenario }>,
s17: () => import("@/data/scenarios/s17.json") as Promise<{ default: Scenario }>,
s18: () => import("@/data/scenarios/s18.json") as Promise<{ default: Scenario }>,
s19: () => import("@/data/scenarios/s19.json") as Promise<{ default: Scenario }>,
};
interface AgentLoopSimulatorProps {

View File

@@ -13,17 +13,15 @@ const visualizations: Record<
s04: lazy(() => import("./s04-hooks")),
s05: lazy(() => import("./s03-todo-write")),
s06: lazy(() => import("./s06-subagent")),
s07: lazy(() => import("./s05-skill-loading")),
s08: lazy(() => import("./s06-context-compact")),
s07: lazy(() => import("./s07-skill-loading")),
s08: lazy(() => import("./s08-context-compact")),
s09: lazy(() => import("./s09-memory")),
s10: lazy(() => import("./s10-system-prompt")),
s11: lazy(() => import("./s11-error-recovery")),
s12: lazy(() => import("./s07-task-system")),
s13: lazy(() => import("./s08-background-tasks")),
s14: lazy(() => import("./s14-cron-scheduler")),
s15: lazy(() => import("./s15-team-runtime")),
s16: lazy(() => import("./s16-mcp-tools")),
s17: lazy(() => import("./s17-integrated-harness")),
s10: lazy(() => import("./s10-task-system")),
s11: lazy(() => import("./s11-background-tasks")),
s12: lazy(() => import("./s12-cron-scheduler")),
s13: lazy(() => import("./s13-team-runtime")),
s14: lazy(() => import("./s14-mcp-tools")),
s15: lazy(() => import("./s15-integrated-harness")),
};
export function SessionVisualization({ version }: { version: string }) {

View File

@@ -7,90 +7,84 @@ import { StepControls } from "@/components/visualizations/shared/step-controls";
interface SkillEntry {
name: string;
summary: string;
fullTokens: number;
content: string[];
}
const SKILLS: SkillEntry[] = [
{
name: "/commit",
summary: "Create git commits following repo conventions",
fullTokens: 320,
name: "code-review",
summary: "Review code for bugs, security, and maintainability",
content: [
"1. Run git status + git diff to see changes",
"2. Analyze all staged changes and draft message",
"3. Create commit with Co-Authored-By trailer",
"4. Run git status after commit to verify",
"# Code Review Skill",
"1. Inspect the change and its surrounding code",
"2. Prioritize bugs and behavioral regressions",
"3. Report missing tests and residual risk",
],
},
{
name: "/review-pr",
summary: "Review pull requests for bugs and style",
fullTokens: 480,
name: "pdf",
summary: "Read, create, and modify PDF files",
content: [
"1. Fetch PR diff via gh pr view",
"2. Analyze changes file by file for issues",
"3. Check for bugs, security, and style problems",
"4. Post review comments with gh pr review",
"# PDF Processing Skill",
"1. Choose text extraction or rendered inspection",
"2. Preserve page order and layout where needed",
"3. Verify the produced PDF before returning it",
],
},
{
name: "/test",
summary: "Run and analyze test suites",
fullTokens: 290,
name: "agent-builder",
summary: "Design and build agents for a target domain",
content: [
"1. Detect test framework from package.json",
"2. Run test suite and capture output",
"3. Analyze failures and suggest fixes",
"4. Re-run after applying fixes",
"# Agent Builder Skill",
"1. Define the agent's task and boundaries",
"2. Select tools and state",
"3. Test the complete loop",
],
},
{
name: "/deploy",
summary: "Deploy application to target environment",
fullTokens: 350,
name: "mcp-builder",
summary: "Build MCP servers and expose external tools",
content: [
"1. Verify all tests pass before deploy",
"2. Build production bundle",
"3. Push to deployment target via CI",
"4. Verify health check on deployed URL",
"# MCP Server Building Skill",
"1. Define tool schemas",
"2. Connect handlers to external services",
"3. Verify discovery and tool calls",
],
},
];
const TOKEN_STATES = [120, 120, 440, 440, 780, 780];
const MAX_TOKEN_DISPLAY = 1000;
const LOADED_STATES = [0, 0, 1, 1, 2, 2];
const STEPS = [
{
title: "Layer 1: Compact Summaries",
title: "Scan the Catalog",
description:
"All skills are summarized in the system prompt. Compact, always present.",
"Startup adds skill names and descriptions to the system prompt.",
},
{
title: "Skill Invocation",
title: "A Specialized Task",
description:
'The model recognizes a skill invocation and triggers the Skill tool.',
"The user asks for work covered by one of the listed skills.",
},
{
title: "Layer 2: Full Injection",
title: "Load the Skill",
description:
"The full skill instructions are injected as a tool_result, not into the system prompt.",
},
{
title: "In Context Now",
title: "Follow the Instructions",
description:
"The detailed instructions appear as if a tool returned them. The model follows them precisely.",
},
{
title: "Stack Skills",
title: "Load Another Skill",
description:
"Multiple skills can be loaded. Only summaries are permanent; full content comes and goes.",
"A later task can load a different SKILL.md through the same tool.",
},
{
title: "Two-Layer Architecture",
title: "Catalog and Full Content",
description:
"Layer 1: always present, tiny. Layer 2: loaded on demand, detailed. Elegant separation.",
"The catalog supports discovery; load_skill returns the selected instructions.",
},
];
@@ -105,7 +99,7 @@ export default function SkillLoading({ title }: { title?: string }) {
toggleAutoPlay,
} = useSteppedVisualization({ totalSteps: STEPS.length, autoPlayInterval: 2500 });
const tokenCount = TOKEN_STATES[currentStep];
const loadedCount = LOADED_STATES[currentStep];
const highlightedSkill = currentStep >= 1 && currentStep <= 3 ? 0 : currentStep >= 4 ? 1 : -1;
const showFirstContent = currentStep >= 2;
const showSecondContent = currentStep >= 4;
@@ -179,10 +173,10 @@ export default function SkillLoading({ title }: { title?: string }) {
className="flex items-center gap-2 rounded-lg border border-blue-200 bg-blue-50 px-3 py-2 dark:border-blue-800 dark:bg-blue-950/30"
>
<span className="text-xs text-blue-600 dark:text-blue-400">
User types:
User asks:
</span>
<code className="rounded bg-blue-100 px-2 py-0.5 text-xs font-bold text-blue-800 dark:bg-blue-900/50 dark:text-blue-200">
/commit
Review this change for bugs and regressions.
</code>
</motion.div>
)}
@@ -194,10 +188,10 @@ export default function SkillLoading({ title }: { title?: string }) {
className="flex items-center gap-2 rounded-lg border border-blue-200 bg-blue-50 px-3 py-2 dark:border-blue-800 dark:bg-blue-950/30"
>
<span className="text-xs text-blue-600 dark:text-blue-400">
User types:
User asks:
</span>
<code className="rounded bg-blue-100 px-2 py-0.5 text-xs font-bold text-blue-800 dark:bg-blue-900/50 dark:text-blue-200">
/review-pr
Extract the tables from this PDF.
</code>
</motion.div>
)}
@@ -239,7 +233,7 @@ export default function SkillLoading({ title }: { title?: string }) {
<div className="flex items-center gap-2">
<div className="h-2 w-2 rounded-full bg-blue-500" />
<span className="text-xs font-bold text-blue-700 dark:text-blue-300">
SKILL.md: /commit
SKILL.md: code-review
</span>
</div>
<span className="rounded bg-blue-100 px-1.5 py-0.5 font-mono text-[10px] text-blue-600 dark:bg-blue-900/40 dark:text-blue-300">
@@ -281,7 +275,7 @@ export default function SkillLoading({ title }: { title?: string }) {
<div className="flex items-center gap-2">
<div className="h-2 w-2 rounded-full bg-purple-500" />
<span className="text-xs font-bold text-purple-700 dark:text-purple-300">
SKILL.md: /review-pr
SKILL.md: pdf
</span>
</div>
<span className="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] text-purple-600 dark:bg-purple-900/40 dark:text-purple-300">
@@ -318,7 +312,7 @@ export default function SkillLoading({ title }: { title?: string }) {
>
The Skill tool returns content as a tool_result message.
The model sees it in context and follows the instructions.
No system prompt bloat.
The full file is now part of the message history.
</motion.div>
)}
</AnimatePresence>
@@ -334,18 +328,18 @@ export default function SkillLoading({ title }: { title?: string }) {
>
<div className="flex-1 rounded border border-zinc-200 bg-zinc-50 p-2 text-center dark:border-zinc-700 dark:bg-zinc-800">
<div className="text-[10px] font-semibold text-zinc-500 dark:text-zinc-400">
LAYER 1
CATALOG
</div>
<div className="text-xs text-zinc-600 dark:text-zinc-300">
Always present, ~120 tokens
Names and descriptions in the system prompt
</div>
</div>
<div className="flex-1 rounded border border-blue-200 bg-blue-50 p-2 text-center dark:border-blue-700 dark:bg-blue-900/20">
<div className="text-[10px] font-semibold text-blue-500 dark:text-blue-400">
LAYER 2
FULL CONTENT
</div>
<div className="text-xs text-blue-600 dark:text-blue-300">
On demand, ~300-500 tokens each
Selected SKILL.md returned by load_skill
</div>
</div>
</motion.div>
@@ -353,10 +347,10 @@ export default function SkillLoading({ title }: { title?: string }) {
</AnimatePresence>
</div>
{/* Token Gauge (vertical bar on the right) */}
{/* Loaded skill count */}
<div className="flex w-16 flex-col items-center">
<div className="mb-1 text-center font-mono text-[10px] text-zinc-400">
Tokens
Loaded
</div>
<div
className="relative w-8 overflow-hidden rounded-full bg-zinc-100 dark:bg-zinc-800"
@@ -364,25 +358,21 @@ export default function SkillLoading({ title }: { title?: string }) {
>
<motion.div
animate={{
height: `${(tokenCount / MAX_TOKEN_DISPLAY) * 100}%`,
height: `${loadedCount * 35}%`,
}}
transition={{ duration: 0.5 }}
className={`absolute bottom-0 w-full rounded-full ${
tokenCount > 600
? "bg-amber-500"
: tokenCount > 300
? "bg-blue-500"
: "bg-emerald-500"
loadedCount > 1 ? "bg-blue-500" : "bg-emerald-500"
}`}
/>
</div>
<motion.div
key={tokenCount}
key={loadedCount}
initial={{ scale: 0.8 }}
animate={{ scale: 1 }}
className="mt-2 text-center font-mono text-xs font-semibold text-zinc-600 dark:text-zinc-300"
>
{tokenCount}
{loadedCount}
</motion.div>
</div>
</div>

View File

@@ -42,7 +42,7 @@ const MEMORY_FILES: MemoryFile[] = [
title: "Verification commands",
filename: "lcc_test_commands.md",
description: "Useful smoke checks for the course website.",
body: "Run npm run build, then browser-check /zh/s09 and /zh/s19.",
body: "Run npm run build, then browser-check /zh/s09 and /zh/s17.",
},
];

View File

@@ -1,260 +0,0 @@
"use client";
import { AnimatePresence, motion } from "framer-motion";
import { Boxes, Brain, CheckCircle2, FileText, KeyRound, Library, Rocket, Wrench } from "lucide-react";
import { StepControls } from "@/components/visualizations/shared/step-controls";
import { useSteppedVisualization } from "@/hooks/useSteppedVisualization";
import { cn } from "@/lib/utils";
const STEPS = [
{
title: "Runtime State Arrives",
desc: "The prompt is not a fixed paragraph; it starts from workspace, tools, memory, and skills.",
mode: "state",
},
{
title: "Section Shelf Selects Owners",
desc: "Each subsystem owns one prompt section, so a bad rule has a place to debug.",
mode: "sections",
},
{
title: "Context Key Checks the Cache",
desc: "The same runtime state produces the same deterministic cache key.",
mode: "cache-miss",
},
{
title: "Prompt Is Assembled",
desc: "Selected sections are joined into one system prompt that the LLM can read.",
mode: "assemble",
},
{
title: "Same Key Reuses the Prompt",
desc: "If nothing changed, the runtime skips assembly and reuses the cached prompt.",
mode: "cache-hit",
},
{
title: "LLM Sees the Built Prompt",
desc: "The model receives a traceable product of runtime state, not a stale hardcoded string.",
mode: "llm",
},
] as const;
const SOURCES = [
{ id: "workspace", label: "workspace", value: "/repo", icon: <Boxes size={16} />, tone: "blue" },
{ id: "tools", label: "tools", value: "bash, read_file", icon: <Wrench size={16} />, tone: "emerald" },
{ id: "memory", label: "memory", value: "enabled", icon: <Brain size={16} />, tone: "amber" },
{ id: "skills", label: "skills", value: "code-review", icon: <Library size={16} />, tone: "violet" },
] as const;
const SECTIONS = [
{ id: "identity", title: "identity", body: "You are a helpful coding agent.", owner: "core" },
{ id: "tools", title: "tools", body: "Available tools: bash, read_file.", owner: "tool registry" },
{ id: "workspace", title: "workspace", body: "Current workspace: /repo.", owner: "runtime" },
{ id: "memory", title: "memory + skills", body: "Load memory index and code-review skill.", owner: "context loader" },
] as const;
type StepMode = (typeof STEPS)[number]["mode"];
type Tone = "blue" | "emerald" | "amber" | "violet" | "zinc";
function toneClass(tone: Tone, active = true) {
if (!active) return "border-zinc-200 bg-white text-zinc-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200";
if (tone === "blue") return "border-blue-200 bg-blue-50 text-blue-800 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-200";
if (tone === "emerald") return "border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900 dark:bg-emerald-950/40 dark:text-emerald-200";
if (tone === "amber") return "border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900 dark:bg-amber-950/40 dark:text-amber-200";
if (tone === "violet") return "border-violet-200 bg-violet-50 text-violet-800 dark:border-violet-900 dark:bg-violet-950/40 dark:text-violet-200";
return "border-zinc-200 bg-zinc-50 text-zinc-700 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200";
}
function Surface({
title,
icon,
active,
children,
}: {
title: string;
icon: React.ReactNode;
active: boolean;
children: React.ReactNode;
}) {
return (
<div
className={cn(
"min-w-0 rounded-lg border p-4 transition-colors",
active
? "border-blue-300 bg-blue-50 dark:border-blue-900 dark:bg-blue-950/30"
: "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900"
)}
>
<div className="mb-4 flex min-w-0 items-center gap-3 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
<span
className={cn(
"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg",
active ? "bg-blue-500 text-white" : "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-300"
)}
>
{icon}
</span>
<span className="min-w-0 text-wrap">{title}</span>
</div>
{children}
</div>
);
}
function SourceCard({
source,
active,
}: {
source: (typeof SOURCES)[number];
active: boolean;
}) {
return (
<motion.div layout animate={active ? { y: -1 } : { y: 0 }} className={cn("rounded-lg border p-3", toneClass(source.tone as Tone, active))}>
<div className="mb-2 flex items-center gap-2 text-sm font-semibold">
{source.icon}
{source.label}
</div>
<code className="block min-w-0 whitespace-pre-wrap break-words rounded bg-white/70 px-2 py-1 font-mono text-xs dark:bg-zinc-950/30">
{source.value}
</code>
</motion.div>
);
}
function SectionCard({
section,
active,
assembled,
}: {
section: (typeof SECTIONS)[number];
active: boolean;
assembled: boolean;
}) {
return (
<motion.div
layout
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
className={cn(
"min-w-0 rounded-lg border p-3",
active || assembled ? toneClass("emerald") : "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900"
)}
>
<div className="mb-1 flex min-w-0 items-center justify-between gap-2">
<div className="min-w-0 break-words font-mono text-sm font-semibold leading-snug">{section.title}</div>
{(active || assembled) && <CheckCircle2 size={15} className="shrink-0" />}
</div>
<div className="mb-2 text-xs leading-relaxed text-zinc-500 dark:text-zinc-400">owner: {section.owner}</div>
<div className="text-sm leading-relaxed text-zinc-700 dark:text-zinc-200">{section.body}</div>
</motion.div>
);
}
function CachePanel({ mode }: { mode: StepMode }) {
const isHit = mode === "cache-hit";
const isActive = mode === "cache-miss" || mode === "cache-hit";
return (
<div className={cn("rounded-lg border p-3", toneClass(isHit ? "emerald" : "amber", isActive))}>
<div className="mb-2 flex items-center gap-2 text-sm font-semibold">
<KeyRound size={16} />
context key
</div>
<code className="block min-w-0 whitespace-pre-wrap break-words rounded bg-white/70 p-2 font-mono text-xs dark:bg-zinc-950/30">
json.dumps(context, sort_keys=True)
</code>
<div className="mt-2 text-sm font-semibold">{isHit ? "cache hit: reuse prompt" : isActive ? "cache miss: assemble sections" : "waiting for state"}</div>
</div>
);
}
function PromptPreview({ mode }: { mode: StepMode }) {
const assembled = mode === "assemble" || mode === "cache-hit" || mode === "llm";
if (!assembled) {
return (
<div className="rounded-lg border border-dashed border-zinc-300 px-4 py-8 text-center text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400">
prompt not built yet
</div>
);
}
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className="space-y-2">
{SECTIONS.map((section) => (
<div key={section.id} className="rounded-lg border border-zinc-200 bg-white p-3 dark:border-zinc-700 dark:bg-zinc-900">
<div className="mb-1 font-mono text-xs font-semibold text-blue-700 dark:text-blue-300">[{section.title}]</div>
<div className="text-sm leading-relaxed text-zinc-700 dark:text-zinc-200">{section.body}</div>
</div>
))}
<div className={cn("rounded-xl border p-4", toneClass(mode === "llm" ? "blue" : "zinc"))}>
<div className="mb-2 flex items-center gap-2 text-base font-semibold">
<Rocket size={17} />
{mode === "llm" ? "sent to LLM" : "system prompt ready"}
</div>
<div className="text-sm leading-relaxed">Traceable prompt text, assembled from named runtime owners.</div>
</div>
</motion.div>
);
}
export default function SystemPromptVisualization({ title }: { title?: string }) {
const vis = useSteppedVisualization({ totalSteps: STEPS.length, autoPlayInterval: 2600 });
const current = STEPS[vis.currentStep];
const mode = current.mode;
const sourceActive = mode === "state" || mode === "sections" || mode === "cache-miss";
const sectionsActive = mode === "sections" || mode === "assemble";
const promptActive = mode === "assemble" || mode === "cache-hit" || mode === "llm";
return (
<section className="min-h-[500px] space-y-4">
<h2 className="text-xl font-semibold text-zinc-900 dark:text-zinc-100">{title || "Runtime Prompt Assembly"}</h2>
<div className="rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-700 dark:bg-zinc-900">
<div className="grid gap-3 xl:grid-cols-[0.95fr_1.1fr_0.95fr]">
<Surface title="Runtime context" icon={<Boxes size={20} />} active={sourceActive}>
<div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-1">
{SOURCES.map((source) => (
<SourceCard key={source.id} source={source} active={sourceActive} />
))}
</div>
</Surface>
<Surface title="Section shelf + cache" icon={<FileText size={20} />} active={sectionsActive || mode === "cache-miss" || mode === "cache-hit"}>
<div className="space-y-3">
<div className="grid gap-2 sm:grid-cols-2">
{SECTIONS.map((section) => (
<SectionCard key={section.id} section={section} active={sectionsActive} assembled={promptActive} />
))}
</div>
<CachePanel mode={mode} />
</div>
</Surface>
<Surface title="System prompt" icon={<Rocket size={20} />} active={promptActive}>
<AnimatePresence mode="wait">
<PromptPreview key={mode} mode={mode} />
</AnimatePresence>
</Surface>
</div>
<div className="mt-3 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm leading-relaxed text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800/70 dark:text-zinc-300">
Beginner rule: system prompts should be assembled from named runtime facts, then cached only when those facts are unchanged.
</div>
<StepControls
className="mt-4"
currentStep={vis.currentStep}
totalSteps={vis.totalSteps}
onPrev={vis.prev}
onNext={vis.next}
onReset={vis.reset}
isPlaying={vis.isPlaying}
onToggleAutoPlay={vis.toggleAutoPlay}
stepTitle={current.title}
stepDescription={current.desc}
/>
</div>
</section>
);
}

View File

@@ -1,347 +0,0 @@
"use client";
import { AnimatePresence, motion } from "framer-motion";
import { Activity, AlertTriangle, Gauge, History, Repeat2, RotateCcw, ShieldCheck, TimerReset, Workflow } from "lucide-react";
import { StepControls } from "@/components/visualizations/shared/step-controls";
import { useSteppedVisualization } from "@/hooks/useSteppedVisualization";
import { cn } from "@/lib/utils";
const STEPS = [
{
title: "Normal Call Still Comes First",
desc: "The runtime starts with a regular LLM call and only enters recovery when a specific failure appears.",
mode: "normal",
},
{
title: "max_tokens Means Output Was Cut Off",
desc: "First recovery is to retry with a larger budget before adding any synthetic continuation message.",
mode: "max-tokens",
},
{
title: "prompt_too_long Means Context Must Shrink",
desc: "The runtime performs reactive compact once, then retries the same task with a smaller message list.",
mode: "prompt-too-long",
},
{
title: "429 Means Wait, Then Retry",
desc: "Rate limits use exponential backoff with jitter so retries do not stampede the provider.",
mode: "rate-limit",
},
{
title: "Repeated 529 Can Switch Models",
desc: "Provider overload increments RecoveryState and can move to a fallback model after repeated failures.",
mode: "overloaded",
},
{
title: "Recovered Calls Return to the Loop",
desc: "Each recovery path is bounded, inspectable, and eventually returns to the normal tool loop or exits cleanly.",
mode: "summary",
},
] as const;
const CASES = [
{
id: "max-tokens",
label: "max_tokens",
symptom: "model stopped mid-answer",
action: "8K -> 64K, retry same request",
state: "token escalated once",
tone: "amber",
},
{
id: "prompt-too-long",
label: "prompt_too_long",
symptom: "context too large",
action: "reactive_compact(messages), retry once",
state: "compact retry used",
tone: "orange",
},
{
id: "rate-limit",
label: "429",
symptom: "rate limited",
action: "backoff + jitter, max 10 retries",
state: "retry attempt counted",
tone: "blue",
},
{
id: "overloaded",
label: "529",
symptom: "provider overloaded",
action: "backoff; 3 consecutive -> fallback model",
state: "consecutive_529 tracked",
tone: "red",
},
] as const;
type StepMode = (typeof STEPS)[number]["mode"];
type CaseId = (typeof CASES)[number]["id"];
type Tone = "amber" | "orange" | "blue" | "red" | "emerald" | "zinc";
function toneClass(tone: Tone, active = true) {
if (!active) return "border-zinc-200 bg-white text-zinc-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200";
if (tone === "amber") return "border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900 dark:bg-amber-950/40 dark:text-amber-200";
if (tone === "orange") return "border-orange-200 bg-orange-50 text-orange-800 dark:border-orange-900 dark:bg-orange-950/40 dark:text-orange-200";
if (tone === "blue") return "border-blue-200 bg-blue-50 text-blue-800 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-200";
if (tone === "red") return "border-red-200 bg-red-50 text-red-800 dark:border-red-900 dark:bg-red-950/40 dark:text-red-200";
if (tone === "emerald") return "border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900 dark:bg-emerald-950/40 dark:text-emerald-200";
return "border-zinc-200 bg-zinc-50 text-zinc-700 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200";
}
function activeCase(mode: StepMode): CaseId | null {
if (mode === "max-tokens") return "max-tokens";
if (mode === "prompt-too-long") return "prompt-too-long";
if (mode === "rate-limit") return "rate-limit";
if (mode === "overloaded") return "overloaded";
return null;
}
function Surface({
title,
icon,
active,
children,
}: {
title: string;
icon: React.ReactNode;
active: boolean;
children: React.ReactNode;
}) {
return (
<div
className={cn(
"min-w-0 rounded-lg border p-4 transition-colors",
active
? "border-red-300 bg-red-50 dark:border-red-900 dark:bg-red-950/30"
: "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900"
)}
>
<div className="mb-4 flex min-w-0 items-center gap-3 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
<span
className={cn(
"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg",
active ? "bg-red-500 text-white" : "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-300"
)}
>
{icon}
</span>
<span className="min-w-0 text-wrap">{title}</span>
</div>
{children}
</div>
);
}
function CaseCard({
item,
active,
muted,
}: {
item: (typeof CASES)[number];
active: boolean;
muted: boolean;
}) {
return (
<motion.div
layout
animate={active ? { y: -1 } : { y: 0 }}
className={cn(
"min-w-0 rounded-lg border p-3",
active ? toneClass(item.tone as Tone) : "border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
muted && "opacity-45"
)}
>
<div className="mb-2 flex min-w-0 items-center justify-between gap-2">
<div className="min-w-0 font-mono text-sm font-semibold">{item.label}</div>
{active && <AlertTriangle size={15} className="shrink-0" />}
</div>
<div className="text-sm leading-relaxed text-zinc-700 dark:text-zinc-200">{item.symptom}</div>
<div className="mt-2 rounded bg-white/70 px-2 py-1 text-xs leading-relaxed dark:bg-zinc-950/30">{item.action}</div>
</motion.div>
);
}
function RecoveryStatePanel({ mode }: { mode: StepMode }) {
const values = {
token: mode === "max-tokens" || mode === "summary" ? "64K used" : "8K",
compact: mode === "prompt-too-long" || mode === "summary" ? "used once" : "unused",
retry: mode === "rate-limit" || mode === "overloaded" || mode === "summary" ? "counting" : "0",
model: mode === "overloaded" ? "fallback ready" : "primary",
};
return (
<div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-1">
{[
["max_tokens", values.token],
["reactive_compact", values.compact],
["retry_attempt", values.retry],
["current_model", values.model],
].map(([label, value]) => (
<div key={label} className="min-w-0 rounded-lg border border-zinc-200 bg-white p-3 dark:border-zinc-700 dark:bg-zinc-900">
<div className="mb-1 font-mono text-xs text-zinc-500 dark:text-zinc-400">{label}</div>
<div className="break-words text-sm font-semibold text-zinc-900 dark:text-zinc-100">{value}</div>
</div>
))}
</div>
);
}
function ActionPanel({ mode }: { mode: StepMode }) {
if (mode === "normal") {
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className={cn("rounded-xl border p-4", toneClass("emerald"))}>
<div className="mb-2 flex items-center gap-2 text-base font-semibold">
<ShieldCheck size={17} />
normal tool loop
</div>
<div className="text-sm leading-relaxed">LLM succeeds, tool_use continues as usual.</div>
</motion.div>
);
}
if (mode === "max-tokens") {
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className={cn("space-y-3 rounded-xl border p-4", toneClass("amber"))}>
<div className="flex items-center gap-2 text-base font-semibold">
<Gauge size={17} />
escalate output budget
</div>
<div className="grid gap-2 sm:grid-cols-2">
<CodePill label="before" value="max_tokens=8000" />
<CodePill label="retry" value="max_tokens=64000" />
</div>
<div className="text-sm leading-relaxed">No fake "continue" user message on the first escalation.</div>
</motion.div>
);
}
if (mode === "prompt-too-long") {
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className={cn("space-y-3 rounded-xl border p-4", toneClass("orange"))}>
<div className="flex items-center gap-2 text-base font-semibold">
<History size={17} />
shrink context, retry once
</div>
<CodePill label="recovery" value="messages = reactive_compact(messages)" />
<div className="text-sm leading-relaxed">If it is still too long after compact, exit cleanly instead of looping forever.</div>
</motion.div>
);
}
if (mode === "rate-limit") {
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className={cn("space-y-3 rounded-xl border p-4", toneClass("blue"))}>
<div className="flex items-center gap-2 text-base font-semibold">
<TimerReset size={17} />
exponential backoff
</div>
<div className="grid grid-cols-3 gap-2 text-center text-xs font-semibold">
{["0.5s", "1s", "2s"].map((delay) => (
<div key={delay} className="rounded bg-white/70 px-2 py-2 dark:bg-zinc-950/30">{delay} + jitter</div>
))}
</div>
<div className="text-sm leading-relaxed">Wait before retrying so the provider has time to recover.</div>
</motion.div>
);
}
if (mode === "overloaded") {
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className={cn("space-y-3 rounded-xl border p-4", toneClass("red"))}>
<div className="flex items-center gap-2 text-base font-semibold">
<RotateCcw size={17} />
fallback model path
</div>
<CodePill label="state" value="consecutive_529 >= 3" />
<CodePill label="action" value="current_model = FALLBACK_MODEL_ID" />
</motion.div>
);
}
return (
<motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className="space-y-2">
{CASES.map((item) => (
<div key={item.id} className={cn("rounded-lg border p-3", toneClass(item.tone as Tone))}>
<div className="mb-1 text-sm font-semibold">{item.label}</div>
<div className="text-xs leading-relaxed opacity-80">{item.state}</div>
</div>
))}
<div className={cn("rounded-xl border p-4", toneClass("emerald"))}>
<div className="mb-2 flex items-center gap-2 text-base font-semibold">
<Repeat2 size={17} />
continue or exit cleanly
</div>
<div className="text-sm leading-relaxed">Every path has a limit, then returns to the normal loop or stops with an explicit error.</div>
</div>
</motion.div>
);
}
function CodePill({ label, value }: { label: string; value: string }) {
return (
<div className="min-w-0 rounded-lg bg-white/70 p-2 dark:bg-zinc-950/30">
<div className="mb-1 text-[11px] font-semibold uppercase tracking-wide opacity-70">{label}</div>
<code className="block min-w-0 whitespace-pre-wrap break-words font-mono text-xs leading-relaxed">{value}</code>
</div>
);
}
export default function ErrorRecoveryVisualization({ title }: { title?: string }) {
const vis = useSteppedVisualization({ totalSteps: STEPS.length, autoPlayInterval: 2600 });
const current = STEPS[vis.currentStep];
const mode = current.mode;
const active = activeCase(mode);
const isSummary = mode === "summary";
return (
<section className="min-h-[500px] space-y-4">
<h2 className="text-xl font-semibold text-zinc-900 dark:text-zinc-100">{title || "Error Recovery Paths"}</h2>
<div className="rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-700 dark:bg-zinc-900">
<div className="grid gap-3 xl:grid-cols-[1fr_0.9fr_1fr]">
<Surface title="Failure inbox" icon={<Activity size={20} />} active={mode !== "normal"}>
<div className="space-y-2">
<div className={cn("rounded-lg border p-3", toneClass("emerald", mode === "normal"))}>
<div className="mb-1 flex items-center gap-2 text-sm font-semibold">
<ShieldCheck size={15} />
success
</div>
<div className="text-sm leading-relaxed">No recovery needed; continue to tool loop.</div>
</div>
{CASES.map((item) => (
<CaseCard key={item.id} item={item} active={active === item.id || isSummary} muted={active !== null && active !== item.id && !isSummary} />
))}
</div>
</Surface>
<Surface title="RecoveryState" icon={<Workflow size={20} />} active={mode !== "normal"}>
<RecoveryStatePanel mode={mode} />
</Surface>
<Surface title="Recovery action" icon={<Repeat2 size={20} />} active>
<AnimatePresence mode="wait">
<ActionPanel key={mode} mode={mode} />
</AnimatePresence>
</Surface>
</div>
<div className="mt-3 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm leading-relaxed text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800/70 dark:text-zinc-300">
Beginner rule: do not blindly retry; classify the failure, run the smallest recovery, and track whether that recovery was already used.
</div>
<StepControls
className="mt-4"
currentStep={vis.currentStep}
totalSteps={vis.totalSteps}
onPrev={vis.prev}
onNext={vis.next}
onReset={vis.reset}
isPlaying={vis.isPlaying}
onToggleAutoPlay={vis.toggleAutoPlay}
stepTitle={current.title}
stepDescription={current.desc}
/>
</div>
</section>
);
}

View File

@@ -24,7 +24,7 @@ const STEPS = [
{
title: "Claim Atomically",
desc: "A ready task moves to one owner while the task-store file lock protects the persisted transition.",
event: "task_store_lock: task_...0042 -> backend",
event: "task_store_lock: task_1a2b3c4d -> backend",
},
{
title: "Require and Review a Plan",
@@ -135,7 +135,7 @@ function TaskPanel({ step }: { step: number }) {
<div className="mt-4 rounded-md border border-zinc-200 p-3 dark:border-zinc-700">
<div className="font-mono text-[11px] text-zinc-500 dark:text-zinc-400">
task_1712345678_0042
task_1a2b3c4d
</div>
<div className="mt-1 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Refactor authentication

View File

@@ -2,45 +2,45 @@
"version": "s10",
"decisions": [
{
"id": "prompt-from-state",
"title": "Model Input Is Built from Runtime State",
"description": "Stable prompt sections and dynamic state are assembled at the model boundary: workspace, available tools, memory, and skills. Model input becomes a product of the runtime rather than a single hardcoded string.",
"alternatives": "A static prompt is easier to inspect, but it goes stale as capabilities change.",
"id": "tasks-as-files",
"title": "Tasks Are Durable JSON Files",
"description": "Each task is persisted under .tasks/ with id, subject, description, status, owner, and blockedBy. The task board survives context compaction and process restarts.",
"alternatives": "In-memory tasks are easier to code, but vanish exactly when long-running coordination needs them most.",
"zh": {
"title": "模型输入由运行时状态构建",
"description": "稳定 prompt section 与动态状态在模型边界组装workspace、可用工具、memory 和 skills。模型输入是运行时的产物而不是单个硬编码字符串。"
"title": "任务是持久 JSON 文件",
"description": "每个任务都持久化在 .tasks/ 下,包含 id、subject、description、status、owner、blockedBy。任务板能跨上下文压缩和进程重启保留。"
},
"ja": {
"title": "モデル入力はランタイム状態から作る",
"description": "安定した prompt section と workspace、利用可能ツール、memory、skills などの動的状態をモデル境界で組み立てます。モデル入力は単一の固定文字列ではなくランタイムの産物です。"
"title": "タスクは永続 JSON ファイル",
"description": "各タスクは .tasks/ に id、subject、description、status、owner、blockedBy を持って保存されます。タスクボードはコンテキスト圧縮や再起動を越えて残ります。"
}
},
{
"id": "deterministic-cache-key",
"title": "A Deterministic Cache Avoids Reassembly",
"description": "The context object is serialized with stable ordering. If the key has not changed, the prompt can be reused safely.",
"alternatives": "Rebuilding every turn is simple, but hides when the prompt actually changed.",
"id": "blockedby-dependencies",
"title": "blockedBy Encodes Ordering",
"description": "A task can only be claimed when all blockedBy dependencies are completed. Missing dependencies are treated as blocked to fail closed.",
"alternatives": "Letting the model remember ordering is fragile and hard for teammates to share.",
"zh": {
"title": "确定性缓存避免重复组装",
"description": "Context 对象用稳定顺序序列化。如果 key 没变,提示词就可以安全复用。"
"title": "blockedBy 编码任务顺序",
"description": "只有所有 blockedBy 依赖都完成时,任务才能被 claim。缺失依赖也被视为阻塞采用 fail closed。"
},
"ja": {
"title": "決定的キャッシュで再組み立てを避ける",
"description": "context オブジェクトを安定した順序でシリアライズします。key が変わらなければプロンプトを安全に再利用できます。"
"title": "blockedBy が順序を表現する",
"description": "blockedBy の依存がすべて完了した時だけタスクを claim できます。存在しない依存もブロック扱いにして fail closed にします。"
}
},
{
"id": "sections-have-owners",
"title": "Prompt Sections Have Owners",
"description": "Identity, tools, workspace, and memory are separate sections. This makes it easier to debug which subsystem injected a bad instruction.",
"alternatives": "Concatenating arbitrary strings works until the prompt grows and no one knows where a rule came from.",
"id": "claim-complete-lifecycle",
"title": "Claim and Complete Make Work Observable",
"description": "claim_task records an owner and in_progress state; complete_task marks completion and reports downstream tasks that became unblocked.",
"alternatives": "A simple checklist can say done, but it cannot safely coordinate ownership or dependencies.",
"zh": {
"title": "Prompt Section 有明确归属",
"description": "identity、tools、workspace、memory 是分开的 section。这样更容易定位哪一层注入了错误指令。"
"title": "Claim 和 Complete 让工作可观察",
"description": "claim_task 记录 owner 和 in_progress 状态complete_task 标记完成,并报告被解锁的下游任务。"
},
"ja": {
"title": "prompt section には所有者がある",
"description": "identity、tools、workspace、memory を別 section にします。どのサブシステムが悪い指示を入れたかを追いやすくなります。"
"title": "claim と complete が作業を観測可能にする",
"description": "claim_task は owner と in_progress を記録し、complete_task は完了を記録して解放された下流タスクを報告します。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s11",
"decisions": [
{
"id": "classified-recovery",
"title": "Different Failures Need Different Recovery Paths",
"description": "max_tokens, prompt_too_long, and provider overload mean different things. The runtime classifies the error before retrying.",
"alternatives": "Blind retry is easy, but wastes time and can repeat a failure that needs compaction or token escalation.",
"id": "explicit-background-boundary",
"title": "Background Work Is an Execution Mode, Not a New Tool",
"description": "The lesson keeps the familiar tool surface and adds a background execution flag around slow operations. That makes the new mechanism visible: the same bash call can either block the loop or be moved to a thread. The agent learns that responsiveness is a runtime concern, not a reason to invent a separate tool for every slow task.",
"alternatives": "A dedicated background_bash tool would be simpler to route, but it would hide the more general idea that any slow operation can be scheduled asynchronously.",
"zh": {
"title": "不同失败需要不同恢复路径",
"description": "max_tokens、prompt_too_long 和供应商过载含义不同。运行时会先分类错误,再决定如何重试。"
"title": "后台任务是执行模式,而不是新工具",
"description": "课程保留原有工具表面,只在慢操作外增加后台执行标记。这样能清楚看到:同一个 bash 调用既可以阻塞主循环也可以放入线程。Agent 学到的是响应性属于运行时问题,而不是每个慢任务都要发明一个新工具。"
},
"ja": {
"title": "失敗ごとに異なる回復経路が必要",
"description": "max_tokens、prompt_too_long、プロバイダ過負荷は意味が違います。ランタイムは再試行前にエラーを分類します。"
"title": "バックグラウンド処理は新ツールではなく実行モード",
"description": "このレッスンでは既存のツール面を保ち、遅い操作にバックグラウンド実行フラグを加えます。同じ bash 呼び出しがループをブロックすることも、スレッドへ移すこともできる点が見えます。応答性はランタイムの責務であり、遅いタスクごとに新しいツールを作る必要はありません。"
}
},
{
"id": "recovery-state",
"title": "RecoveryState Prevents Infinite Retries",
"description": "The runtime tracks token escalation, compact retries, consecutive 529s, and fallback model use. Recovery becomes bounded and inspectable.",
"alternatives": "A while-retry loop can accidentally retry forever or hide which mitigation has already run.",
"id": "notification-reentry",
"title": "Completed Threads Re-enter as Notifications",
"description": "Background results are injected as task notifications instead of pretending to be immediate tool results. This preserves the chronology of the conversation: the model first sees that work started, and later sees that a task completed.",
"alternatives": "The thread could mutate the last tool result in place, but that would make the transcript impossible to reason about and hard to replay.",
"zh": {
"title": "RecoveryState 防止无限重试",
"description": "运行时记录 token 升级、compact retry、连续 529、fallback model 等状态。恢复因此有边界、可检查。"
"title": "线程完成后以通知形式回到循环",
"description": "后台结果会作为任务通知注入,而不是伪装成立即返回的 tool result。这样保留了对话时间线模型先看到任务已启动之后再看到任务完成。"
},
"ja": {
"title": "RecoveryState が無限リトライを防ぐ",
"description": "token 拡張、compact retry、連続 529、fallback model の利用を追跡します。回復処理に境界と可観測性を与えます。"
"title": "完了したスレッドは通知として戻る",
"description": "バックグラウンド結果は即時の tool result ではなくタスク通知として注入されます。モデルはまず作業開始を見て、その後に完了を知るため、会話の時系列が保たれます。"
}
},
{
"id": "no-fake-continuation",
"title": "Do Not Fake User Messages During Token Recovery",
"description": "The first max_tokens escalation retries without appending a synthetic user prompt. The transcript should reflect real events, not internal recovery tricks.",
"alternatives": "Always appending 'continue' is tempting, but it pollutes conversation history and may change model behavior.",
"id": "shared-result-store",
"title": "A Small Shared Store Keeps Threads Observable",
"description": "The implementation tracks background task state and results in explicit dictionaries. That keeps the code teachable while still exposing the hard parts of concurrency: ids, lifecycle state, and safe collection.",
"alternatives": "A full queue or job database adds durability, but it would obscure the minimal moving parts needed to understand threaded agent work.",
"zh": {
"title": "Token 恢复时不伪造用户消息",
"description": "第一次 max_tokens 升级会直接重试,不追加合成 user prompt。Transcript 应反映真实事件,而不是内部恢复技巧。"
"title": "小型共享存储让线程可观察",
"description": "实现用显式字典记录后台任务状态和结果。这样代码仍然易学,同时暴露并发中的关键问题:任务 id、生命周期状态和结果收集。"
},
"ja": {
"title": "トークン回復で偽のユーザーメッセージを入れない",
"description": "最初の max_tokens 拡張では合成 user prompt を追加せず再試行します。transcript は内部の回復処理ではなく実際の出来事を反映すべきです。"
"title": "小さな共有ストアでスレッドを観測可能にする",
"description": "実装は辞書でバックグラウンドタスクの状態と結果を追跡します。コードを学びやすく保ちながら、id、ライフサイクル、安全な収集という並行処理の要点を示します。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s12",
"decisions": [
{
"id": "tasks-as-files",
"title": "Tasks Are Durable JSON Files",
"description": "Each task is persisted under .tasks/ with id, subject, description, status, owner, and blockedBy. The task board survives context compaction and process restarts.",
"alternatives": "In-memory tasks are easier to code, but vanish exactly when long-running coordination needs them most.",
"id": "scheduler-outside-agent-loop",
"title": "The Scheduler Runs Outside the Agent Loop",
"description": "Cron matching is handled by a daemon loop rather than by asking the LLM to remember future times. This separates timekeeping from reasoning and makes recurring work reliable even when no user is actively chatting.",
"alternatives": "The agent could poll schedules inside each conversation turn, but missed turns would mean missed jobs.",
"zh": {
"title": "任务是持久 JSON 文件",
"description": "每个任务都持久化在 .tasks/ 下,包含 id、subject、description、status、owner、blockedBy。任务板能跨上下文压缩和进程重启保留。"
"title": "调度器运行在 Agent 循环之外",
"description": "Cron 匹配由独立守护循环处理,而不是让 LLM 记住未来时间。这把计时和推理分开,使定期任务在没有用户对话时也能可靠触发。"
},
"ja": {
"title": "タスクは永続 JSON ファイル",
"description": "各タスクは .tasks/ に id、subject、description、status、owner、blockedBy を持って保存されます。タスクボードはコンテキスト圧縮や再起動を越えて残ります。"
"title": "スケジューラはエージェントループの外で動く",
"description": "cron の照合は LLM に未来時刻を覚えさせるのではなく、デーモンループで処理します。時間管理と推論を分離し、ユーザーが会話していない時でも定期処理を確実にします。"
}
},
{
"id": "blockedby-dependencies",
"title": "blockedBy Encodes Ordering",
"description": "A task can only be claimed when all blockedBy dependencies are completed. Missing dependencies are treated as blocked to fail closed.",
"alternatives": "Letting the model remember ordering is fragile and hard for teammates to share.",
"id": "queue-decouples-time-from-work",
"title": "A Queue Decouples Due Time from Execution",
"description": "When a schedule matches, the scheduler enqueues work and lets a queue processor invoke the agent loop. That keeps cron matching fast and prevents long agent runs from blocking future schedule checks.",
"alternatives": "The scheduler could call the agent directly, but a slow job would stall the scheduler itself.",
"zh": {
"title": "blockedBy 编码任务顺序",
"description": "只有所有 blockedBy 依赖都完成时,任务才能被 claim。缺失依赖也被视为阻塞采用 fail closed。"
"title": "队列把到期判断和任务执行解耦",
"description": "当 schedule 匹配时,调度器只把任务放入队列,由队列处理器调用 agent_loop。这样 cron 匹配保持快速,长时间运行的 agent 任务不会阻塞后续调度检查。"
},
"ja": {
"title": "blockedBy が順序を表現する",
"description": "blockedBy の依存がすべて完了した時だけタスクを claim できます。存在しない依存もブロック扱いにして fail closed にします。"
"title": "キューが期限判定と実行を分離する",
"description": "スケジュールが一致すると、スケジューラは作業をキューへ入れ、キュープロセッサが agent_loop を呼び出します。cron 照合は速く保たれ、長いエージェント実行が次の確認を妨げません。"
}
},
{
"id": "claim-complete-lifecycle",
"title": "Claim and Complete Make Work Observable",
"description": "claim_task records an owner and in_progress state; complete_task marks completion and reports downstream tasks that became unblocked.",
"alternatives": "A simple checklist can say done, but it cannot safely coordinate ownership or dependencies.",
"id": "durable-schedules",
"title": "Schedules Are Durable Data",
"description": "Cron jobs are stored in a small JSON file so they survive process restarts. The lesson treats scheduled work as data that can be listed, cancelled, and inspected, not as hidden timers.",
"alternatives": "In-memory timers are shorter to implement, but they disappear on restart and are difficult to audit.",
"zh": {
"title": "Claim 和 Complete 让工作可观察",
"description": "claim_task 记录 owner 和 in_progress 状态complete_task 标记完成,并报告被解锁的下游任务。"
"title": "计划任务是持久数据",
"description": "Cron job 存储在小型 JSON 文件中,因此进程重启后仍然存在。课程把计划任务视为可列出、可取消、可检查的数据,而不是隐藏的计时器。"
},
"ja": {
"title": "claim と complete が作業を観測可能にする",
"description": "claim_task は owner と in_progress を記録し、complete_task は完了を記録して解放された下流タスクを報告します。"
"title": "スケジュールは永続データ",
"description": "cron ジョブは小さな JSON ファイルに保存され、プロセス再起動後も残ります。予定された作業を、一覧化、取り消し、検査できるデータとして扱います。"
}
}
]

View File

@@ -2,45 +2,101 @@
"version": "s13",
"decisions": [
{
"id": "explicit-background-boundary",
"title": "Background Work Is an Execution Mode, Not a New Tool",
"description": "The lesson keeps the familiar tool surface and adds a background execution flag around slow operations. That makes the new mechanism visible: the same bash call can either block the loop or be moved to a thread. The agent learns that responsiveness is a runtime concern, not a reason to invent a separate tool for every slow task.",
"alternatives": "A dedicated background_bash tool would be simpler to route, but it would hide the more general idea that any slow operation can be scheduled asynchronously.",
"id": "confirm-team-before-spawn",
"title": "The User Confirms the Team Before It Starts",
"description": "The Lead may notice that a request can be split, but it first proposes a small team with clear responsibilities. Teammates start only after the user confirms the extra agents.",
"alternatives": "Spawning immediately saves one turn, but hides the cost and coordination choice from the user.",
"zh": {
"title": "后台任务是执行模式,而不是新工具",
"description": "课程保留原有工具表面,只在慢操作外增加后台执行标记。这样能清楚看到:同一个 bash 调用既可以阻塞主循环也可以放入线程。Agent 学到的是响应性属于运行时问题,而不是每个慢任务都要发明一个新工具。"
"title": "启动团队前先征得用户确认",
"description": "Lead 可以判断一个需求适合拆分,但要先提出职责清晰的小团队。只有用户确认后,运行时才启动额外的 Agent。"
},
"ja": {
"title": "バックグラウンド処理は新ツールではなく実行モード",
"description": "このレッスンでは既存のツール面を保ち、遅い操作にバックグラウンド実行フラグを加えます。同じ bash 呼び出しがループをブロックすることも、スレッドへ移すこともできる点が見えます。応答性はランタイムの責務であり、遅いタスクごとに新しいツールを作る必要はありません。"
"title": "チームを起動する前にユーザーが確認する",
"description": "Lead は依頼を分割できると判断しても、まず役割が明確な小さなチームを提案する。追加 Agent はユーザーの確認後に起動する。"
}
},
{
"id": "notification-reentry",
"title": "Completed Threads Re-enter as Notifications",
"description": "Background results are injected as task notifications instead of pretending to be immediate tool results. This preserves the chronology of the conversation: the model first sees that work started, and later sees that a task completed.",
"alternatives": "The thread could mutate the last tool result in place, but that would make the transcript impossible to reason about and hard to replay.",
"id": "runtime-owned-delivery",
"title": "Message Delivery Belongs to the Runtime",
"description": "The MessageBus persists each handoff, while the runtime watches the Lead mailbox and injects new team events into the next turn. The model does not spend turns polling an inbox.",
"alternatives": "A model-visible check_inbox tool is easy to add, but wastes turns and can leave completed work unnoticed.",
"zh": {
"title": "线程完成后以通知形式回到循环",
"description": "后台结果会作为任务通知注入,而不是伪装成立即返回的 tool result。这样保留了对话时间线模型先看到任务已启动之后再看到任务完成。"
"title": "消息投递由运行时负责",
"description": "MessageBus 持久化每次交接,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要浪费轮次轮询收件箱。"
},
"ja": {
"title": "完了したスレッドは通知として戻る",
"description": "バックグラウンド結果は即時の tool result ではなくタスク通知として注入されます。モデルはまず作業開始を見て、その後に完了を知るため、会話の時系列が保たれます。"
"title": "メッセージ配信はランタイムが担う",
"description": "MessageBus が各ハンドオフを永続化し、ランタイムが Lead の受信箱を監視して新しい team event を次の turn に注入する。モデルは受信箱のポーリングに turn を費やさない。"
}
},
{
"id": "shared-result-store",
"title": "A Small Shared Store Keeps Threads Observable",
"description": "The implementation tracks background task state and results in explicit dictionaries. That keeps the code teachable while still exposing the hard parts of concurrency: ids, lifecycle state, and safe collection.",
"alternatives": "A full queue or job database adds durability, but it would obscure the minimal moving parts needed to understand threaded agent work.",
"id": "typed-request-correlation",
"title": "Typed Requests Carry Correlation IDs",
"description": "Plan and shutdown requests use explicit message types and request ids. Replies can arrive in any order and still update the correct pending request.",
"alternatives": "Matching the latest free-form message works only until requests overlap.",
"zh": {
"title": "小型共享存储让线程可观察",
"description": "实现用显式字典记录后台任务状态和结果。这样代码仍然易学,同时暴露并发中的关键问题:任务 id、生命周期状态和结果收集。"
"title": "类型化请求携带关联 ID",
"description": "计划和关机请求使用明确的消息类型与 request id。即使回复顺序不同运行时也能更新正确的 pending request。"
},
"ja": {
"title": "小さな共有ストアでスレッドを観測可能にする",
"description": "実装は辞書でバックグラウンドタスクの状態と結果を追跡します。コードを学びやすく保ちながら、id、ライフサイクル、安全な収集という並行処理の要点を示します。"
"title": "型付きリクエストに対応 ID を持たせる",
"description": "プランと終了の要求は明示的な message type と request id を使う。返信順が変わっても、正しい pending request を更新できる。"
}
},
{
"id": "plan-approval-is-a-gate",
"title": "Plan Approval Is an Execution Gate",
"description": "When the Lead requests a plan, mutating tools remain blocked until the matching plan is approved. Rejection requires a new submission rather than a conversational workaround.",
"alternatives": "Treating approval as a suggestion cannot prevent an early write or shell command.",
"zh": {
"title": "计划审批是执行闸门",
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交,不能靠对话绕过。"
},
"ja": {
"title": "プラン承認を実行ゲートにする",
"description": "Lead がプランを要求すると、対応するプランが承認されるまで変更系ツールをブロックする。却下後は会話で迂回せず再提出が必要になる。"
}
},
{
"id": "idle-claim-is-atomic",
"title": "Idle Discovery and Claiming Form One Safe Path",
"description": "An idle teammate scans only pending, unowned tasks whose dependencies are complete. The ownership check and pending-to-in_progress update happen under one lock, so two teammates cannot claim the same work.",
"alternatives": "Central dispatch keeps assignment simple, while an unlocked scan can assign the same task twice.",
"zh": {
"title": "空闲发现与原子认领组成一条安全路径",
"description": "空闲队友只扫描 pending、未分配且依赖已完成的任务。所有权检查与 pending 到 in_progress 的更新在同一把锁内完成,因此两个队友不会认领同一任务。"
},
"ja": {
"title": "待機中の探索と原子的な認領を一つの安全な経路にする",
"description": "待機中のチームメイトは pending、未所有、依存解決済みのタスクだけを探す。所有権確認と pending から in_progress への更新を同じ lock 内で行い、二重認領を防ぐ。"
}
},
{
"id": "task-bound-worktree",
"title": "The Working Directory Is a Task Property",
"description": "A task records its worktree binding, and a teammate's bash, read, and write tools derive their working directory from the claimed task. This is explicit cwd routing for parallel edits, not a security sandbox or a second orchestration system.",
"alternatives": "Letting agents switch directories implicitly is shorter, but makes the cwd boundary invisible and easy to lose.",
"zh": {
"title": "工作目录是任务的显式属性",
"description": "任务记录自己的 worktree 绑定,队友的 bash、read、write 工具从已认领任务推导工作目录。这是为并行编辑提供的显式 cwd 路由,不是安全沙箱,也不是第二套编排系统。"
},
"ja": {
"title": "作業ディレクトリをタスクの明示的な属性にする",
"description": "タスクが worktree の紐付けを保持し、チームメイトの bash、read、write は認領したタスクから作業ディレクトリを決める。これは並行編集のための明示的な cwd routing であり、security sandbox や第二の編成システムではない。"
}
},
{
"id": "worktree-cleanup-fails-closed",
"title": "Worktree Cleanup Fails Closed",
"description": "Creation binds a task only after git succeeds. Removal accepts only a known path under the worktree root and refuses unverifiable or dirty state unless discard is explicit; it never completes the task as a side effect.",
"alternatives": "Unconditional force removal is convenient, but can destroy unreviewed work and blur task completion with directory cleanup.",
"zh": {
"title": "Worktree 清理默认拒绝不安全操作",
"description": "只有 git 创建成功后才绑定任务。删除仅接受 worktree 根目录下的已知路径;状态无法验证或存在未保存改动时,除非明确选择丢弃,否则拒绝删除,并且不会顺带完成任务。"
},
"ja": {
"title": "Worktree の片付けは安全側に失敗する",
"description": "git の作成成功後にだけタスクを紐付ける。削除は worktree ルート配下の既知パスだけを受け付け、状態を確認できない場合や変更が残る場合は明示的な破棄なしに拒否し、タスクを副作用で完了させない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s14",
"decisions": [
{
"id": "scheduler-outside-agent-loop",
"title": "The Scheduler Runs Outside the Agent Loop",
"description": "Cron matching is handled by a daemon loop rather than by asking the LLM to remember future times. This separates timekeeping from reasoning and makes recurring work reliable even when no user is actively chatting.",
"alternatives": "The agent could poll schedules inside each conversation turn, but missed turns would mean missed jobs.",
"id": "normalized-mcp-namespace",
"title": "MCP Tools Use a Normalized Namespace",
"description": "Discovered tools are exposed as mcp__server__tool. The prefix makes the source explicit and avoids collisions with built-in tools or tools from another server.",
"alternatives": "Using the raw tool name is shorter, but search from two servers could overwrite each other.",
"zh": {
"title": "调度器运行在 Agent 循环之外",
"description": "Cron 匹配由独立守护循环处理,而不是让 LLM 记住未来时间。这把计时和推理分开,使定期任务在没有用户对话时也能可靠触发。"
"title": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
},
"ja": {
"title": "スケジューラはエージェントループの外で動く",
"description": "cron の照合は LLM に未来時刻を覚えさせるのではなく、デーモンループで処理します。時間管理と推論を分離し、ユーザーが会話していない時でも定期処理を確実にします。"
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
}
},
{
"id": "queue-decouples-time-from-work",
"title": "A Queue Decouples Due Time from Execution",
"description": "When a schedule matches, the scheduler enqueues work and lets a queue processor invoke the agent loop. That keeps cron matching fast and prevents long agent runs from blocking future schedule checks.",
"alternatives": "The scheduler could call the agent directly, but a slow job would stall the scheduler itself.",
"id": "dynamic-tool-pool",
"title": "Tool Discovery Updates the Active Tool Pool",
"description": "After connecting to a server, the runtime assembles a new tool pool for the next LLM call. The model can only use MCP tools after discovery has made them visible.",
"alternatives": "Preloading every possible MCP tool would create a huge prompt and expose capabilities the user did not request.",
"zh": {
"title": "队列把到期判断和任务执行解耦",
"description": "当 schedule 匹配时,调度器只把任务放入队列,由队列处理器调用 agent_loop。这样 cron 匹配保持快速,长时间运行的 agent 任务不会阻塞后续调度检查。"
"title": "工具发现会更新活动工具池",
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
},
"ja": {
"title": "キューが期限判定と実行を分離する",
"description": "スケジュールが一致すると、スケジューラは作業をキューへ入れ、キュープロセッサが agent_loop を呼び出します。cron 照合は速く保たれ、長いエージェント実行が次の確認を妨げません。"
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
}
},
{
"id": "durable-schedules",
"title": "Schedules Are Durable Data",
"description": "Cron jobs are stored in a small JSON file so they survive process restarts. The lesson treats scheduled work as data that can be listed, cancelled, and inspected, not as hidden timers.",
"alternatives": "In-memory timers are shorter to implement, but they disappear on restart and are difficult to audit.",
"id": "external-results-append-like-tools",
"title": "External Results Reuse the Tool Result Path",
"description": "MCP responses are appended to the conversation like ordinary tool results. This keeps the agent loop unchanged while still letting external systems participate.",
"alternatives": "A separate external-response channel would make MCP feel special and require extra loop logic.",
"zh": {
"title": "计划任务是持久数据",
"description": "Cron job 存储在小型 JSON 文件中,因此进程重启后仍然存在。课程把计划任务视为可列出、可取消、可检查的数据,而不是隐藏的计时器。"
"title": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
},
"ja": {
"title": "スケジュールは永続データ",
"description": "cron ジョブは小さな JSON ファイルに保存され、プロセス再起動後も残ります。予定された作業を、一覧化、取り消し、検査できるデータとして扱います。"
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
}
}
]

View File

@@ -2,101 +2,45 @@
"version": "s15",
"decisions": [
{
"id": "confirm-team-before-spawn",
"title": "The User Confirms the Team Before It Starts",
"description": "The Lead may notice that a request can be split, but it first proposes a small team with clear responsibilities. Teammates start only after the user confirms the extra agents.",
"alternatives": "Spawning immediately saves one turn, but hides the cost and coordination choice from the user.",
"id": "composition-over-new-loop",
"title": "The Harness Composes Previous Layers",
"description": "The integrated harness does not replace the loop with a new architecture. It composes memory, tasks, skills, background work, teams, worktrees, and MCP around the same core model-tool-result cycle.",
"alternatives": "A new orchestration framework would look more impressive, but it would hide the continuity across the course.",
"zh": {
"title": "启动团队前先征得用户确认",
"description": "Lead 可以判断一个需求适合拆分,但要先提出职责清晰的小团队。只有用户确认后,运行时才启动额外的 Agent。"
"title": "Harness 组合既有层,而不是换掉循环",
"description": "集成后的 Harness 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
},
"ja": {
"title": "チームを起動する前にユーザーが確認する",
"description": "Lead は依頼を分割できると判断しても、まず役割が明確な小さなチームを提案する。追加 Agent はユーザーの確認後に起動する。"
"title": "Harness は既存レイヤーを統合する",
"description": "統合された Harness はループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
}
},
{
"id": "runtime-owned-delivery",
"title": "Message Delivery Belongs to the Runtime",
"description": "The MessageBus persists each handoff, while the runtime watches the Lead mailbox and injects new team events into the next turn. The model does not spend turns polling an inbox.",
"alternatives": "A model-visible check_inbox tool is easy to add, but wastes turns and can leave completed work unnoticed.",
"id": "single-source-of-runtime-truth",
"title": "Runtime State Has Named Sources",
"description": "Context assembly pulls from named sources such as memory, task graph, skills, tool registry, and policy. This keeps a large agent debuggable because each piece of prompt context has an owner.",
"alternatives": "Dumping everything into one prompt string is shorter, but it becomes impossible to tell which subsystem caused a bad decision.",
"zh": {
"title": "消息投递由运行时负责",
"description": "MessageBus 持久化每次交接,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要浪费轮次轮询收件箱。"
"title": "运行时状态来自具名来源",
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
},
"ja": {
"title": "メッセージ配信はランタイムが担う",
"description": "MessageBus が各ハンドオフを永続化し、ランタイムが Lead の受信箱を監視して新しい team event を次の turn に注入する。モデルは受信箱のポーリングに turn を費やさない。"
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
}
},
{
"id": "typed-request-correlation",
"title": "Typed Requests Carry Correlation IDs",
"description": "Plan and shutdown requests use explicit message types and request ids. Replies can arrive in any order and still update the correct pending request.",
"alternatives": "Matching the latest free-form message works only until requests overlap.",
"id": "recovery-is-first-class",
"title": "Recovery Is Part of the Main Flow",
"description": "Compaction, error recovery, and asynchronous result collection are normal loop behavior. The harness handles recovery and resumption through named paths instead of scattered exception branches.",
"alternatives": "Leaving recovery at the edges makes it harder to see which state is safe to resume.",
"zh": {
"title": "类型化请求携带关联 ID",
"description": "计划和关机请求使用明确的消息类型与 request id。即使回复顺序不同运行时也能更新正确的 pending request。"
"title": "恢复能力是一等流程",
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
},
"ja": {
"title": "型付きリクエストに対応 ID を持たせる",
"description": "プランと終了の要求は明示的な message type と request id を使う。返信順が変わっても、正しい pending request を更新できる。"
}
},
{
"id": "plan-approval-is-a-gate",
"title": "Plan Approval Is an Execution Gate",
"description": "When the Lead requests a plan, mutating tools remain blocked until the matching plan is approved. Rejection requires a new submission rather than a conversational workaround.",
"alternatives": "Treating approval as a suggestion cannot prevent an early write or shell command.",
"zh": {
"title": "计划审批是执行闸门",
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交,不能靠对话绕过。"
},
"ja": {
"title": "プラン承認を実行ゲートにする",
"description": "Lead がプランを要求すると、対応するプランが承認されるまで変更系ツールをブロックする。却下後は会話で迂回せず再提出が必要になる。"
}
},
{
"id": "idle-claim-is-atomic",
"title": "Idle Discovery and Claiming Form One Safe Path",
"description": "An idle teammate scans only pending, unowned tasks whose dependencies are complete. The ownership check and pending-to-in_progress update happen under one lock, so two teammates cannot claim the same work.",
"alternatives": "Central dispatch keeps assignment simple, while an unlocked scan can assign the same task twice.",
"zh": {
"title": "空闲发现与原子认领组成一条安全路径",
"description": "空闲队友只扫描 pending、未分配且依赖已完成的任务。所有权检查与 pending 到 in_progress 的更新在同一把锁内完成,因此两个队友不会认领同一任务。"
},
"ja": {
"title": "待機中の探索と原子的な認領を一つの安全な経路にする",
"description": "待機中のチームメイトは pending、未所有、依存解決済みのタスクだけを探す。所有権確認と pending から in_progress への更新を同じ lock 内で行い、二重認領を防ぐ。"
}
},
{
"id": "task-bound-worktree",
"title": "The Working Directory Is a Task Property",
"description": "A task records its worktree binding, and a teammate's bash, read, and write tools derive their working directory from the claimed task. This is explicit cwd routing for parallel edits, not a security sandbox or a second orchestration system.",
"alternatives": "Letting agents switch directories implicitly is shorter, but makes the cwd boundary invisible and easy to lose.",
"zh": {
"title": "工作目录是任务的显式属性",
"description": "任务记录自己的 worktree 绑定,队友的 bash、read、write 工具从已认领任务推导工作目录。这是为并行编辑提供的显式 cwd 路由,不是安全沙箱,也不是第二套编排系统。"
},
"ja": {
"title": "作業ディレクトリをタスクの明示的な属性にする",
"description": "タスクが worktree の紐付けを保持し、チームメイトの bash、read、write は認領したタスクから作業ディレクトリを決める。これは並行編集のための明示的な cwd routing であり、security sandbox や第二の編成システムではない。"
}
},
{
"id": "worktree-cleanup-fails-closed",
"title": "Worktree Cleanup Fails Closed",
"description": "Creation binds a task only after git succeeds. Removal accepts only a known path under the worktree root and refuses unverifiable or dirty state unless discard is explicit; it never completes the task as a side effect.",
"alternatives": "Unconditional force removal is convenient, but can destroy unreviewed work and blur task completion with directory cleanup.",
"zh": {
"title": "Worktree 清理默认拒绝不安全操作",
"description": "只有 git 创建成功后才绑定任务。删除仅接受 worktree 根目录下的已知路径;状态无法验证或存在未保存改动时,除非明确选择丢弃,否则拒绝删除,并且不会顺带完成任务。"
},
"ja": {
"title": "Worktree の片付けは安全側に失敗する",
"description": "git の作成成功後にだけタスクを紐付ける。削除は worktree ルート配下の既知パスだけを受け付け、状態を確認できない場合や変更が残る場合は明示的な破棄なしに拒否し、タスクを副作用で完了させない。"
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s16",
"decisions": [
{
"id": "normalized-mcp-namespace",
"title": "MCP Tools Use a Normalized Namespace",
"description": "Discovered tools are exposed as mcp__server__tool. The prefix makes the source explicit and avoids collisions with built-in tools or tools from another server.",
"alternatives": "Using the raw tool name is shorter, but search from two servers could overwrite each other.",
"id": "script-owns-fixed-orchestration",
"title": "Code Owns Fixed Orchestration",
"description": "When the stages and aggregation rules are known in advance, a workflow script makes the process parallel, reproducible, and inspectable without changing the main agent loop.",
"alternatives": "Letting the model choose every next step is more flexible, but slower and harder to resume for a fixed procedure.",
"zh": {
"title": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
},
"ja": {
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
}
},
{
"id": "dynamic-tool-pool",
"title": "Tool Discovery Updates the Active Tool Pool",
"description": "After connecting to a server, the runtime assembles a new tool pool for the next LLM call. The model can only use MCP tools after discovery has made them visible.",
"alternatives": "Preloading every possible MCP tool would create a huge prompt and expose capabilities the user did not request.",
"id": "semantic-journal-keys",
"title": "Semantic Keys Make Resume Independent of Completion Order",
"description": "Journal entries use stable call content rather than a shared completion counter. Concurrent calls can finish in any order and still map to the correct cached result.",
"alternatives": "Indexing by completion order is simpler, but replays the wrong result as soon as concurrent timing changes.",
"zh": {
"title": "工具发现会更新活动工具池",
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
},
"ja": {
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
}
},
{
"id": "external-results-append-like-tools",
"title": "External Results Reuse the Tool Result Path",
"description": "MCP responses are appended to the conversation like ordinary tool results. This keeps the agent loop unchanged while still letting external systems participate.",
"alternatives": "A separate external-response channel would make MCP feel special and require extra loop logic.",
"id": "fail-the-workflow",
"title": "Orchestration Failures Propagate",
"description": "A failed stage, invalid structured result, corrupt journal, or exceeded run-wide limit fails the workflow instead of silently dropping an item and reporting success.",
"alternatives": "Best-effort collection can be useful for optional work, but it must be explicit rather than the default.",
"zh": {
"title": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
},
"ja": {
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s17",
"decisions": [
{
"id": "composition-over-new-loop",
"title": "The Harness Composes Previous Layers",
"description": "The integrated harness does not replace the loop with a new architecture. It composes memory, tasks, skills, background work, teams, worktrees, and MCP around the same core model-tool-result cycle.",
"alternatives": "A new orchestration framework would look more impressive, but it would hide the continuity across the course.",
"id": "host-owns-completion-gate",
"title": "The Host Owns the Completion Gate",
"description": "The working model may request to stop, but GoalController evaluates the active goal before AgentSession returns. The gate sits at the existing turn boundary.",
"alternatives": "Asking the working model whether it is finished is simpler, but lets the same actor make and verify its own claim.",
"zh": {
"title": "Harness 组合既有层,而不是换掉循环",
"description": "集成后的 Harness 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
"title": "完成闸门由宿主持有",
"description": "工作模型可以请求停止,但 GoalController 会在 AgentSession 返回前评估 active goal。这个闸门就在原有的轮次边界上。"
},
"ja": {
"title": "Harness は既存レイヤーを統合する",
"description": "統合された Harness はループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
"title": "完了ゲートはホストが所有する",
"description": "作業モデルは停止を要求できますが、GoalController は AgentSession が return する前に active goal を評価します。この gate は既存の turn 境界に置かれます。"
}
},
{
"id": "single-source-of-runtime-truth",
"title": "Runtime State Has Named Sources",
"description": "Context assembly pulls from named sources such as memory, task graph, skills, tool registry, and policy. This keeps a large agent debuggable because each piece of prompt context has an owner.",
"alternatives": "Dumping everything into one prompt string is shorter, but it becomes impossible to tell which subsystem caused a bad decision.",
"id": "conversation-is-evaluator-input",
"title": "The Conversation Is the Evaluator's Input",
"description": "The evaluator receives the active condition and the current conversation, including tool results reported there. It has no tools of its own and judges only what the conversation contains.",
"alternatives": "Letting the evaluator rerun commands would turn a completion check into another worker and create a second execution path.",
"zh": {
"title": "运行时状态来自具名来源",
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
"title": "对话记录就是判断器的输入",
"description": "判断器接收 active condition 和当前对话,其中也包括已经写入的工具结果。它自己没有工具,只能根据对话中已有的内容判断。"
},
"ja": {
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
"title": "conversation が evaluator の入力になる",
"description": "evaluator は active condition と現在の conversation を受け取り、そこに記録された tool result も読みます。自身では tool を使えず、conversation にある内容だけで判断します。"
}
},
{
"id": "recovery-is-first-class",
"title": "Recovery Is Part of the Main Flow",
"description": "Compaction, error recovery, and asynchronous result collection are normal loop behavior. The harness handles recovery and resumption through named paths instead of scattered exception branches.",
"alternatives": "Leaving recovery at the edges makes it harder to see which state is safe to resume.",
"id": "continuation-limits-preserve-goal",
"title": "Limits Return Control Without Clearing the Goal",
"description": "When a goal is unmet, the controller appends the evaluator's reason to messages[] and continues the same loop. The Stop-hook block cap or global turn limit returns control to the user while leaving the goal active.",
"alternatives": "Continuing without any limit can hold one request forever; marking the goal complete or clearing it at the limit would lose unfinished work.",
"zh": {
"title": "恢复能力是一等流程",
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
"title": "达到限制时交还控制权,但保留目标",
"description": "目标未满足时controller 把判断理由追加到 messages[]并在同一个循环里继续。Stop hook 的连续阻止上限或全局轮次上限会把控制权交还用户,同时让目标保持 active。"
},
"ja": {
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
"title": "上限では control を返し、goal は維持する",
"description": "goal が未達なら、controller は evaluator の理由を messages[] に追加し、同じ loop を続けます。Stop hook の連続 block 上限または global turn limit に達すると、goal を active のまま user に control を返します。"
}
}
]

View File

@@ -1,47 +0,0 @@
{
"version": "s18",
"decisions": [
{
"id": "script-owns-fixed-orchestration",
"title": "Code Owns Fixed Orchestration",
"description": "When the stages and aggregation rules are known in advance, a workflow script makes the process parallel, reproducible, and inspectable without changing the main agent loop.",
"alternatives": "Letting the model choose every next step is more flexible, but slower and harder to resume for a fixed procedure.",
"zh": {
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
},
"ja": {
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
}
},
{
"id": "semantic-journal-keys",
"title": "Semantic Keys Make Resume Independent of Completion Order",
"description": "Journal entries use stable call content rather than a shared completion counter. Concurrent calls can finish in any order and still map to the correct cached result.",
"alternatives": "Indexing by completion order is simpler, but replays the wrong result as soon as concurrent timing changes.",
"zh": {
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
},
"ja": {
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
}
},
{
"id": "fail-the-workflow",
"title": "Orchestration Failures Propagate",
"description": "A failed stage, invalid structured result, corrupt journal, or exceeded run-wide limit fails the workflow instead of silently dropping an item and reporting success.",
"alternatives": "Best-effort collection can be useful for optional work, but it must be explicit rather than the default.",
"zh": {
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
},
"ja": {
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
}
}
]
}

View File

@@ -1,47 +0,0 @@
{
"version": "s19",
"decisions": [
{
"id": "host-owns-completion-gate",
"title": "The Host Owns the Completion Gate",
"description": "The working model may request to stop, but GoalController evaluates the active goal before AgentSession returns. The gate sits at the existing turn boundary.",
"alternatives": "Asking the working model whether it is finished is simpler, but lets the same actor make and verify its own claim.",
"zh": {
"title": "完成闸门由宿主持有",
"description": "工作模型可以请求停止,但 GoalController 会在 AgentSession 返回前评估 active goal。这个闸门就在原有的轮次边界上。"
},
"ja": {
"title": "完了ゲートはホストが所有する",
"description": "作業モデルは停止を要求できますが、GoalController は AgentSession が return する前に active goal を評価します。この gate は既存の turn 境界に置かれます。"
}
},
{
"id": "conversation-is-evaluator-input",
"title": "The Conversation Is the Evaluator's Input",
"description": "The evaluator receives the active condition and the current conversation, including tool results reported there. It has no tools of its own and judges only what the conversation contains.",
"alternatives": "Letting the evaluator rerun commands would turn a completion check into another worker and create a second execution path.",
"zh": {
"title": "对话记录就是判断器的输入",
"description": "判断器接收 active condition 和当前对话,其中也包括已经写入的工具结果。它自己没有工具,只能根据对话中已有的内容判断。"
},
"ja": {
"title": "conversation が evaluator の入力になる",
"description": "evaluator は active condition と現在の conversation を受け取り、そこに記録された tool result も読みます。自身では tool を使えず、conversation にある内容だけで判断します。"
}
},
{
"id": "continuation-limits-preserve-goal",
"title": "Limits Return Control Without Clearing the Goal",
"description": "When a goal is unmet, the controller appends the evaluator's reason to messages[] and continues the same loop. The Stop-hook block cap or global turn limit returns control to the user while leaving the goal active.",
"alternatives": "Continuing without any limit can hold one request forever; marking the goal complete or clearing it at the limit would lose unfinished work.",
"zh": {
"title": "达到限制时交还控制权,但保留目标",
"description": "目标未满足时controller 把判断理由追加到 messages[]并在同一个循环里继续。Stop hook 的连续阻止上限或全局轮次上限会把控制权交还用户,同时让目标保持 active。"
},
"ja": {
"title": "上限では control を返し、goal は維持する",
"description": "goal が未達なら、controller は evaluator の理由を messages[] に追加し、同じ loop を続けます。Stop hook の連続 block 上限または global turn limit に達すると、goal を active のまま user に control を返します。"
}
}
]
}

View File

@@ -49,266 +49,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "append", to: "llm" },
],
},
s03: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "todo", label: "Create Todos", type: "process", x: COL_CENTER, y: 100 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 180 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 260 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 340 },
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 410 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 340 },
],
edges: [
{ from: "start", to: "todo" },
{ from: "todo", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "exec", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s04: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "is_task", label: "task tool?", type: "decision", x: COL_LEFT, y: 280 },
{ id: "spawn", label: "Spawn Subagent\n(fresh messages[])", type: "subprocess", x: 60, y: 380 },
{ id: "sub_loop", label: "Subagent Loop", type: "process", x: 60, y: 460 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 380 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 540 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_task", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_task", to: "spawn", label: "task" },
{ from: "is_task", to: "exec", label: "other" },
{ from: "spawn", to: "sub_loop" },
{ from: "sub_loop", to: "append" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s05: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "is_skill", label: "load_skill?", type: "decision", x: COL_LEFT, y: 280 },
{ id: "load", label: "Read SKILL.md", type: "subprocess", x: 60, y: 370 },
{ id: "inject", label: "Inject via\ntool_result", type: "process", x: 60, y: 450 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_skill", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_skill", to: "load", label: "skill" },
{ from: "is_skill", to: "exec", label: "other" },
{ from: "load", to: "inject" },
{ from: "inject", to: "append" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s06: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "compress_check", label: "Over token\nlimit?", type: "decision", x: COL_CENTER, y: 110 },
{ id: "compress", label: "Compress Context", type: "subprocess", x: COL_RIGHT, y: 110 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 200 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 280 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 360 },
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 430 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 360 },
],
edges: [
{ from: "start", to: "compress_check" },
{ from: "compress_check", to: "compress", label: "yes" },
{ from: "compress_check", to: "llm", label: "no" },
{ from: "compress", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "exec", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "exec", to: "append" },
{ from: "append", to: "compress_check" },
],
},
s07: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "is_task", label: "task_manager?", type: "decision", x: COL_LEFT, y: 280 },
{ id: "crud", label: "CRUD Task\n(file-based)", type: "subprocess", x: 60, y: 370 },
{ id: "dep_check", label: "Check\nDependencies", type: "process", x: 60, y: 450 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_task", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_task", to: "crud", label: "task" },
{ from: "is_task", to: "exec", label: "other" },
{ from: "crud", to: "dep_check" },
{ from: "dep_check", to: "append" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s08: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "bg_check", label: "Background?", type: "decision", x: COL_LEFT, y: 280 },
{ id: "bg_spawn", label: "Spawn Thread", type: "subprocess", x: 60, y: 370 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 450 },
{ id: "notify", label: "Notification\nQueue", type: "process", x: 60, y: 450 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "bg_check", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "bg_check", to: "bg_spawn", label: "bg" },
{ from: "bg_check", to: "exec", label: "fg" },
{ from: "bg_spawn", to: "notify" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
{ from: "notify", to: "llm" },
],
},
s09: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call\n(team lead)", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "is_team", label: "Team tool?", type: "decision", x: COL_LEFT, y: 290 },
{ id: "spawn", label: "Spawn\nTeammate", type: "subprocess", x: 60, y: 390 },
{ id: "msg", label: "Send Message\n(JSONL inbox)", type: "subprocess", x: 60, y: 470 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 390 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 550 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 290 },
{ id: "teammate", label: "Teammate Agent\n(own loop)", type: "process", x: COL_RIGHT, y: 470 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_team", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_team", to: "spawn", label: "spawn" },
{ from: "is_team", to: "exec", label: "other" },
{ from: "spawn", to: "teammate" },
{ from: "spawn", to: "msg" },
{ from: "msg", to: "append" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s10: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call\n(team lead)", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "is_proto", label: "Protocol?", type: "decision", x: COL_LEFT, y: 290 },
{ id: "shutdown", label: "Shutdown\nRequest", type: "subprocess", x: 60, y: 390 },
{ id: "fsm", label: "FSM:\npending->approved", type: "process", x: 60, y: 470 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 390 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 550 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 290 },
{ id: "teammate", label: "Teammate\nreceives request_id", type: "process", x: COL_RIGHT, y: 470 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_proto", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_proto", to: "shutdown", label: "shutdown" },
{ from: "is_proto", to: "exec", label: "other" },
{ from: "shutdown", to: "fsm" },
{ from: "fsm", to: "teammate" },
{ from: "teammate", to: "append" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
],
},
s11: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "inbox", label: "Check Inbox", type: "process", x: COL_CENTER, y: 100 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 180 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 260 },
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 340 },
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 410 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 340 },
{ id: "idle", label: "Idle Cycle", type: "process", x: COL_RIGHT, y: 420 },
{ id: "poll", label: "Poll Tasks\n+ Auto-Claim", type: "subprocess", x: COL_RIGHT, y: 500 },
],
edges: [
{ from: "start", to: "inbox" },
{ from: "inbox", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "exec", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "exec", to: "append" },
{ from: "append", to: "llm" },
{ from: "end", to: "idle" },
{ from: "idle", to: "poll" },
{ from: "poll", to: "inbox" },
],
},
s12: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "is_wt", label: "worktree tool?", type: "decision", x: COL_LEFT, y: 280 },
{ id: "task", label: "Task Board\\n(.tasks)", type: "process", x: 60, y: 360 },
{ id: "wt_create", label: "Allocate / Enter\\nWorktree", type: "subprocess", x: 60, y: 440 },
{ id: "wt_run", label: "Run in\\nIsolated Dir", type: "subprocess", x: COL_LEFT + 80, y: 360 },
{ id: "wt_close", label: "Closeout:\\nworktree_keep / remove", type: "process", x: COL_LEFT + 80, y: 440 },
{ id: "events", label: "Emit Lifecycle Events\\n(side-channel)", type: "process", x: COL_RIGHT, y: 420 },
{ id: "events_read", label: "Optional Read\\nworktree_events", type: "subprocess", x: COL_RIGHT, y: 520 },
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
],
edges: [
{ from: "start", to: "llm" },
{ from: "llm", to: "tool_check" },
{ from: "tool_check", to: "is_wt", label: "yes" },
{ from: "tool_check", to: "end", label: "no" },
{ from: "is_wt", to: "task", label: "task ops" },
{ from: "is_wt", to: "wt_create", label: "create/bind" },
{ from: "is_wt", to: "wt_run", label: "run/status" },
{ from: "task", to: "wt_create", label: "allocate lane" },
{ from: "wt_create", to: "wt_run" },
{ from: "task", to: "append", label: "task result" },
{ from: "wt_create", to: "events", label: "emit create" },
{ from: "wt_create", to: "append", label: "create result" },
{ from: "wt_run", to: "wt_close" },
{ from: "wt_run", to: "append", label: "run/status result" },
{ from: "wt_close", to: "events", label: "emit closeout" },
{ from: "wt_close", to: "append", label: "closeout result" },
{ from: "events", to: "events_read", label: "optional query" },
{ from: "events_read", to: "append", label: "events result" },
{ from: "append", to: "llm" },
],
},
s13: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
@@ -338,7 +79,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "append", to: "llm" },
],
},
s14: {
s12: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
@@ -366,7 +107,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "agent", to: "llm" },
],
},
s15: {
s13: {
nodes: [
{ id: "start", label: "User Requirement", type: "start", x: COL_CENTER, y: 30 },
{ id: "lead", label: "Lead Proposes\nSmall Team", type: "process", x: COL_CENTER, y: 110 },
@@ -401,7 +142,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "bus", to: "lead", label: "runtime delivery" },
],
},
s16: {
s14: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
@@ -428,7 +169,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "append", to: "llm" },
],
},
s17: {
s15: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "context", label: "Assemble Context\nmemory + tasks", type: "process", x: COL_CENTER, y: 115 },
@@ -462,7 +203,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "recover", to: "context" },
],
},
s18: {
s16: {
nodes: [
{ id: "start", label: "Workflow Tool Call", type: "start", x: COL_CENTER, y: 30 },
{ id: "validate", label: "Validate Meta +\nPermission", type: "process", x: COL_CENTER, y: 120 },
@@ -486,7 +227,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "output", to: "notify" },
],
},
s19: {
s17: {
nodes: [
{ id: "start", label: "Model Wants to Stop", type: "start", x: COL_CENTER, y: 30 },
{ id: "active", label: "Active Goal?", type: "decision", x: COL_CENTER, y: 120 },
@@ -697,58 +438,6 @@ const CURRENT_FLOW_OVERRIDES: Record<string, FlowDefinition> = {
],
},
s10: {
nodes: [
{ id: "start", label: "Runtime State", type: "start", x: COL_CENTER, y: 30 },
{ id: "sections", label: "PROMPT_SECTIONS", type: "process", x: COL_CENTER, y: 120 },
{ id: "context", label: "Build Context\nmemory/tools/workspace", type: "process", x: COL_CENTER, y: 220 },
{ id: "cache", label: "Cache Hit?", type: "decision", x: COL_CENTER, y: 320 },
{ id: "reuse", label: "Reuse Prompt", type: "process", x: COL_RIGHT, y: 420 },
{ id: "assemble", label: "Assemble Prompt", type: "subprocess", x: COL_LEFT, y: 420 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 540 },
{ id: "loop", label: "Tool Loop", type: "subprocess", x: COL_CENTER, y: 640 },
],
edges: [
{ from: "start", to: "sections" },
{ from: "sections", to: "context" },
{ from: "context", to: "cache" },
{ from: "cache", to: "reuse", label: "yes" },
{ from: "cache", to: "assemble", label: "no" },
{ from: "reuse", to: "llm" },
{ from: "assemble", to: "llm" },
{ from: "llm", to: "loop" },
{ from: "loop", to: "context" },
],
},
s11: {
nodes: [
{ id: "start", label: "LLM Request", type: "start", x: COL_CENTER, y: 30 },
{ id: "try", label: "try LLM Call", type: "process", x: COL_CENTER, y: 120 },
{ id: "ok", label: "success?", type: "decision", x: COL_CENTER, y: 220 },
{ id: "tools", label: "Execute Tools", type: "process", x: COL_RIGHT, y: 330 },
{ id: "classify", label: "Classify Error", type: "decision", x: COL_LEFT, y: 330 },
{ id: "tokens", label: "max_tokens\nEscalate", type: "subprocess", x: 40, y: 440 },
{ id: "prompt", label: "prompt_too_long\nCompact", type: "subprocess", x: COL_LEFT, y: 610 },
{ id: "backoff", label: "429 / 529\nBackoff", type: "subprocess", x: COL_LEFT + 140, y: 440 },
{ id: "fallback", label: "Fallback Model", type: "process", x: COL_RIGHT, y: 540 },
{ id: "retry", label: "Retry Request", type: "process", x: COL_CENTER, y: 740 },
],
edges: [
{ from: "start", to: "try" },
{ from: "try", to: "ok" },
{ from: "ok", to: "tools", label: "yes" },
{ from: "ok", to: "classify", label: "error" },
{ from: "classify", to: "tokens", label: "max_tokens" },
{ from: "classify", to: "prompt", label: "too long" },
{ from: "classify", to: "backoff", label: "429/529" },
{ from: "backoff", to: "fallback", label: "repeated 529" },
{ from: "tokens", to: "retry" },
{ from: "prompt", to: "retry" },
{ from: "backoff", to: "retry" },
{ from: "fallback", to: "retry" },
{ from: "retry", to: "try" },
],
},
s12: {
nodes: [
{ id: "start", label: "User Goal", type: "start", x: COL_CENTER, y: 30 },
{ id: "create", label: "create_task", type: "subprocess", x: COL_CENTER, y: 120 },

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,27 +1,48 @@
{
"version": "s10",
"title": "Context Assembly",
"description": "Stable instructions and dynamic runtime state are assembled at the model boundary and cached by a deterministic context key.",
"title": "Task System",
"description": "A file-persisted task graph tracks status, ownership, and blockedBy dependencies.",
"steps": [
{
"type": "system_event",
"content": "context={workspace:\"/repo\", memories:true, skills:[\"code-review\"], tools:[\"bash\",\"read_file\"]}",
"annotation": "Prompt inputs are explicit runtime data."
"type": "user_message",
"content": "Break the release into tasks and block deployment until tests pass.",
"annotation": "The user asks for durable multi-step coordination."
},
{
"type": "system_event",
"content": "cache miss -> assemble_system_prompt(context)",
"annotation": "A new context key causes sections to be selected and joined."
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Run tests\"}",
"annotation": "Tasks are created as JSON files under .tasks/."
},
{
"type": "assistant_text",
"content": "I can use the workspace, memory index, tool guidance, and available skills for this task.",
"annotation": "The LLM sees the assembled prompt, not a hardcoded static string."
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Deploy release\",\"blockedBy\":[\"task_tests\"]}",
"annotation": "blockedBy encodes dependency ordering."
},
{
"type": "system_event",
"content": "same context key -> reuse cached prompt",
"annotation": "Repeated turns avoid rebuilding identical prompt text."
"type": "tool_call",
"toolName": "claim_task",
"content": "{\"task_id\":\"task_deploy\",\"owner\":\"agent\"}",
"annotation": "The claim fails until dependencies are complete."
},
{
"type": "tool_result",
"toolName": "claim_task",
"content": "Blocked by: [\"task_tests\"]",
"annotation": "The task graph prevents premature work."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_tests\"}",
"annotation": "Completing a dependency can unblock downstream tasks."
},
{
"type": "tool_result",
"toolName": "complete_task",
"content": "Completed task_tests\nUnblocked: Deploy release",
"annotation": "The harness reports newly available work."
}
]
}

View File

@@ -1,33 +1,45 @@
{
"version": "s11",
"title": "Error Recovery",
"description": "LLM calls are wrapped with targeted recovery paths for token limits, prompt overflow, and transient provider errors.",
"title": "Background Tasks",
"description": "Long-running work moves to a thread while the agent keeps the main loop responsive.",
"steps": [
{
"type": "system_event",
"content": "try LLM call with max_tokens=8000",
"annotation": "The normal path is still a regular model call."
"type": "user_message",
"content": "Run a long repository scan and tell me when it finishes.",
"annotation": "The user asks for work that may exceed the normal foreground loop."
},
{
"type": "system_event",
"content": "error=max_tokens -> escalate to 64000 without appending a fake user message",
"annotation": "Token exhaustion gets a continuation-aware recovery path."
},
{
"type": "system_event",
"content": "error=prompt_too_long -> reactive_compact(messages) -> retry once",
"annotation": "Prompt overflow triggers compaction instead of blind retry."
},
{
"type": "system_event",
"content": "error=529 -> exponential backoff with jitter; repeated 529 -> fallback model",
"annotation": "Transient provider errors use backoff and model fallback."
"type": "assistant_text",
"content": "I'll start the scan in the background so we can keep the conversation responsive.",
"annotation": "The model chooses the background path instead of blocking on the tool result."
},
{
"type": "tool_call",
"toolName": "read_file",
"content": "{\"path\":\"README.md\"}",
"annotation": "After recovery succeeds, the agent continues the normal tool loop."
"toolName": "bash",
"content": "rg \"TODO|FIXME\" .",
"toolInput": "{\"background\":true}",
"annotation": "The tool call is wrapped with a background flag."
},
{
"type": "system_event",
"content": "background_tasks[task_42] = Thread(target=run_bash)",
"annotation": "The runtime starts a thread and returns immediately."
},
{
"type": "tool_result",
"toolName": "bash",
"content": "Started background task task_42.",
"annotation": "A placeholder result is appended to the main conversation."
},
{
"type": "system_event",
"content": "<task_notification id=\"task_42\" status=\"done\">Found 12 matches.</task_notification>",
"annotation": "The completed thread injects a notification back into the next loop."
},
{
"type": "assistant_text",
"content": "The scan finished with 12 matches. I'll summarize the most important ones now.",
"annotation": "The agent consumes the background result as fresh context."
}
]
}

View File

@@ -1,48 +1,44 @@
{
"version": "s12",
"title": "Task System",
"description": "A file-persisted task graph tracks status, ownership, and blockedBy dependencies.",
"title": "Cron Scheduler",
"description": "A daemon loop watches durable cron definitions, queues due jobs, and lets the agent process them.",
"steps": [
{
"type": "user_message",
"content": "Break the release into tasks and block deployment until tests pass.",
"annotation": "The user asks for durable multi-step coordination."
"content": "Every weekday morning, remind me to review open tasks.",
"annotation": "The user asks for a recurring future action."
},
{
"type": "assistant_text",
"content": "I'll create a cron job and store it so the scheduler can pick it up later.",
"annotation": "The agent delegates recurrence to the scheduler instead of relying on current context."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Run tests\"}",
"annotation": "Tasks are created as JSON files under .tasks/."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Deploy release\",\"blockedBy\":[\"task_tests\"]}",
"annotation": "blockedBy encodes dependency ordering."
},
{
"type": "tool_call",
"toolName": "claim_task",
"content": "{\"task_id\":\"task_deploy\",\"owner\":\"agent\"}",
"annotation": "The claim fails until dependencies are complete."
"toolName": "schedule_cron",
"content": "{\"name\":\"review-open-tasks\",\"cron\":\"0 9 * * 1-5\",\"prompt\":\"Review open tasks and summarize blockers.\"}",
"annotation": "The new tool validates and persists a cron definition."
},
{
"type": "tool_result",
"toolName": "claim_task",
"content": "Blocked by: [\"task_tests\"]",
"annotation": "The task graph prevents premature work."
"toolName": "schedule_cron",
"content": "Scheduled review-open-tasks with id cron_7.",
"annotation": "The job is written to the durable schedule store."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_tests\"}",
"annotation": "Completing a dependency can unblock downstream tasks."
"type": "system_event",
"content": "cron_scheduler_loop: cron_7 matched current minute -> cron_queue.put(cron_7)",
"annotation": "The independent scheduler daemon detects that the job is due."
},
{
"type": "tool_result",
"toolName": "complete_task",
"content": "Completed task_tests\nUnblocked: Deploy release",
"annotation": "The harness reports newly available work."
"type": "system_event",
"content": "queue_processor_loop: dequeued cron_7 and invoked agent_loop(prompt)",
"annotation": "A separate processor turns due jobs into normal agent work."
},
{
"type": "assistant_text",
"content": "Scheduled. When the cron fires, the queue processor will run the reminder prompt through the agent loop.",
"annotation": "The final answer explains the durable recurring behavior."
}
]
}

View File

@@ -1,45 +1,122 @@
{
"version": "s13",
"title": "Background Tasks",
"description": "Long-running work moves to a thread while the agent keeps the main loop responsive.",
"title": "Agent Team Runtime",
"description": "The Lead coordinates persistent teammates while the runtime owns message delivery, atomic task claims, and task-bound worktree directories.",
"steps": [
{
"type": "user_message",
"content": "Run a long repository scan and tell me when it finishes.",
"annotation": "The user asks for work that may exceed the normal foreground loop."
"content": "Refactor authentication and update its dependent tests in parallel without mixing the edits.",
"annotation": "The user states the outcome and parallel-edit boundary, not an implementation-specific worktree procedure."
},
{
"type": "assistant_text",
"content": "I'll start the scan in the background so we can keep the conversation responsive.",
"annotation": "The model chooses the background path instead of blocking on the tool result."
"content": "I propose a backend teammate for authentication and a test teammate that picks up the dependent checks once they are ready. Shall I start the team?",
"annotation": "The Lead makes the extra-agent decision visible before spawning."
},
{
"type": "user_message",
"content": "Yes, go ahead.",
"annotation": "The team starts only after explicit confirmation."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "rg \"TODO|FIXME\" .",
"toolInput": "{\"background\":true}",
"annotation": "The tool call is wrapped with a background flag."
},
{
"type": "system_event",
"content": "background_tasks[task_42] = Thread(target=run_bash)",
"annotation": "The runtime starts a thread and returns immediately."
"toolName": "create_task",
"content": "{\"subject\":\"Refactor authentication\"}",
"annotation": "The shared task board remains the source of ownership and status."
},
{
"type": "tool_result",
"toolName": "bash",
"content": "Started background task task_42.",
"annotation": "A placeholder result is appended to the main conversation."
"toolName": "create_task",
"content": "Created task_1a2b3c4d: Refactor authentication",
"annotation": "The runtime-generated task ID is carried into every later operation on this task."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"name\":\"auth-refactor\",\"task_id\":\"task_1a2b3c4d\"}",
"annotation": "The worktree directory is recorded on the task instead of managed as a separate workflow or security sandbox."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update authentication tests\",\"blockedBy\":[\"task_1a2b3c4d\"]}",
"annotation": "The task graph keeps dependent work from starting early."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_5e6f7a8b: Update authentication tests (blockedBy: task_1a2b3c4d)",
"annotation": "The second generated ID names the dependent task that the test teammate will later claim."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Review the assigned authentication task and propose a plan.\",\"task_id\":\"task_1a2b3c4d\",\"require_plan\":true}",
"annotation": "The runtime claims the initial task and activates the plan gate before the teammate thread starts."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"tests\",\"role\":\"test engineer\",\"prompt\":\"Watch the board and claim the dependent test task when it becomes ready.\"}",
"annotation": "A second persistent teammate can wait in IDLE without another direct dispatch."
},
{
"type": "system_event",
"content": "<task_notification id=\"task_42\" status=\"done\">Found 12 matches.</task_notification>",
"annotation": "The completed thread injects a notification back into the next loop."
"content": "spawn_teammate(backend, task_1a2b3c4d) -> task_store_lock commits owner=backend before thread start",
"annotation": "The ownership check and persisted state transition share the cross-process task-store lock."
},
{
"type": "tool_call",
"toolName": "request_plan",
"content": "{\"teammate\":\"backend\",\"task\":\"Inspect the claimed authentication task and submit a plan before changing files.\"}",
"annotation": "The Lead delivers the plan request for the current assignment; the gate was already active before the teammate thread started."
},
{
"type": "system_event",
"content": "backend submit_plan -> plan_approval_request(request_id=req_000007, task_id=task_1a2b3c4d)",
"annotation": "The request records the task and work version that the plan is meant to authorize."
},
{
"type": "tool_call",
"toolName": "review_plan",
"content": "{\"request_id\":\"req_000007\",\"approve\":true,\"feedback\":\"Proceed with the scoped refactor.\"}",
"annotation": "Approval is correlated by request ID and cannot carry into a different assignment."
},
{
"type": "system_event",
"content": "plan_approval_response(request_id=req_000007, approve=true) -> backend",
"annotation": "The teammate receives the typed response before mutating tools are released."
},
{
"type": "system_event",
"content": "backend tool cwd -> .worktrees/auth-refactor",
"annotation": "Bash, read, and write derive their directory from the claimed task binding."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_1a2b3c4d\"}",
"annotation": "Completing the first task makes its dependent test task ready."
},
{
"type": "system_event",
"content": "backend -> Lead: result(auth refactor complete) -> idle_notification",
"annotation": "The task directory stays selected through the completion turn, then IDLE releases the assignment."
},
{
"type": "system_event",
"content": "claim_next_task(tests) -> task_5e6f7a8b; task_store_lock commits owner=tests",
"annotation": "An idle teammate discovers newly ready work without another direct assignment."
},
{
"type": "system_event",
"content": "tests -> Lead: result(test suite passed) -> idle_notification",
"annotation": "The runtime wakes the Lead when mailbox events arrive instead of asking the model to poll."
},
{
"type": "assistant_text",
"content": "The scan finished with 12 matches. I'll summarize the most important ones now.",
"annotation": "The agent consumes the background result as fresh context."
"content": "Authentication was refactored in its task-bound worktree and the dependent tests pass.",
"annotation": "The Lead combines parallel results into one user-facing outcome."
}
]
}

View File

@@ -1,44 +1,46 @@
{
"version": "s14",
"title": "Cron Scheduler",
"description": "A daemon loop watches durable cron definitions, queues due jobs, and lets the agent process them.",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"steps": [
{
"type": "user_message",
"content": "Every weekday morning, remind me to review open tasks.",
"annotation": "The user asks for a recurring future action."
},
{
"type": "assistant_text",
"content": "I'll create a cron job and store it so the scheduler can pick it up later.",
"annotation": "The agent delegates recurrence to the scheduler instead of relying on current context."
"content": "Search the documentation for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
},
{
"type": "tool_call",
"toolName": "schedule_cron",
"content": "{\"name\":\"review-open-tasks\",\"cron\":\"0 9 * * 1-5\",\"prompt\":\"Review open tasks and summarize blockers.\"}",
"annotation": "The new tool validates and persists a cron definition."
"toolName": "connect_mcp",
"content": "{\"name\":\"docs\"}",
"annotation": "The runtime creates an MCP client for the named server."
},
{
"type": "system_event",
"content": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
},
{
"type": "tool_result",
"toolName": "schedule_cron",
"content": "Scheduled review-open-tasks with id cron_7.",
"annotation": "The job is written to the durable schedule store."
"toolName": "connect_mcp",
"content": "Connected to MCP server 'docs'. Discovered 2 tools: search, get_version",
"annotation": "Tool discovery expands the active tool pool."
},
{
"type": "system_event",
"content": "cron_scheduler_loop: cron_7 matched current minute -> cron_queue.put(cron_7)",
"annotation": "The independent scheduler daemon detects that the job is due."
"type": "tool_call",
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "system_event",
"content": "queue_processor_loop: dequeued cron_7 and invoked agent_loop(prompt)",
"annotation": "A separate processor turns due jobs into normal agent work."
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[docs] Found 3 results for 'deployment'",
"annotation": "The external result is appended like any other tool result."
},
{
"type": "assistant_text",
"content": "Scheduled. When the cron fires, the queue processor will run the reminder prompt through the agent loop.",
"annotation": "The final answer explains the durable recurring behavior."
"content": "The docs server found three matches for deployment guidance.",
"annotation": "The agent summarizes external tool output for the user."
}
]
}

View File

@@ -1,122 +1,102 @@
{
"version": "s15",
"title": "Agent Team Runtime",
"description": "The Lead coordinates persistent teammates while the runtime owns message delivery, atomic task claims, and task-bound worktree directories.",
"title": "Integrated Harness",
"description": "The harness combines system instructions, tools, memory, teams, background work, cron, worktrees, and MCP.",
"steps": [
{
"type": "user_message",
"content": "Refactor authentication and update its dependent tests in parallel without mixing the edits.",
"annotation": "The user states the outcome and parallel-edit boundary, not an implementation-specific worktree procedure."
"content": "Prepare this project for release. Check the code, update the docs, and report deployment readiness.",
"annotation": "One ordinary request needs several earlier capabilities to work together."
},
{
"type": "system_event",
"content": "assemble_prompt: memory + task graph + skills + available tools + policy",
"annotation": "The runtime builds the prompt from layered sources of context."
},
{
"type": "assistant_text",
"content": "I propose a backend teammate for authentication and a test teammate that picks up the dependent checks once they are ready. Shall I start the team?",
"annotation": "The Lead makes the extra-agent decision visible before spawning."
"content": "I suggest a docs teammate while I run the release checks and inspect deployment status. Shall I start that team?",
"annotation": "The Lead proposes the team before adding another persistent agent."
},
{
"type": "user_message",
"content": "Yes, go ahead.",
"annotation": "The team starts only after explicit confirmation."
"content": "Yes. Start the docs teammate and continue.",
"annotation": "User confirmation opens the team boundary inherited from S13."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"code-review\"}",
"annotation": "Skills contribute procedural context before execution."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Refactor authentication\"}",
"annotation": "The shared task board remains the source of ownership and status."
"content": "{\"subject\":\"Update release notes\",\"description\":\"Prepare release documentation and report the result.\"}",
"annotation": "The shared task board gives the docs work a stable owner and lifecycle."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0042: Refactor authentication",
"annotation": "The runtime-generated task ID is carried into every later operation on this task."
"content": "Created task_1712345678_0042: Update release notes",
"annotation": "The task ID connects the assignment to its working directory."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"name\":\"auth-refactor\",\"task_id\":\"task_1712345678_0042\"}",
"annotation": "The worktree directory is recorded on the task instead of managed as a separate workflow or security sandbox."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update authentication tests\",\"blockedBy\":[\"task_1712345678_0042\"]}",
"annotation": "The task graph keeps dependent work from starting early."
"content": "{\"name\":\"release-docs\",\"task_id\":\"task_1712345678_0042\"}",
"annotation": "The pending docs task receives a separate checkout before it is claimed."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0043: Update authentication tests (blockedBy: task_1712345678_0042)",
"annotation": "The second generated ID names the dependent task that the test teammate will later claim."
"toolName": "create_worktree",
"content": "Worktree 'release-docs' created for task_1712345678_0042",
"annotation": "The task now carries the checkout used by its eventual owner."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Claim the authentication task and propose a plan.\",\"require_plan\":true}",
"annotation": "The plan gate is active before the teammate thread starts, so claim and mutation cannot race ahead of approval."
"content": "{\"name\":\"docs\",\"role\":\"documentation engineer\",\"prompt\":\"Claim task_1712345678_0042, update the release notes in its task-bound worktree, and report the result.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"tests\",\"role\":\"test engineer\",\"prompt\":\"Watch the board and claim the dependent test task when it becomes ready.\"}",
"annotation": "A second persistent teammate can wait in IDLE without another direct dispatch."
"toolName": "bash",
"content": "{\"command\":\"python -m unittest tests.test_agent_teams_runtime\",\"run_in_background\":true}",
"annotation": "Long-running validation goes through the background task path."
},
{
"type": "system_event",
"content": "claim_next_task(backend) -> task_1712345678_0042; task_store_lock commits owner=backend",
"annotation": "The ownership check and persisted state transition share the cross-process task-store lock."
"content": "permission: user approved the exact test command",
"annotation": "Team confirmation does not authorize shell execution; the foreground turn asks separately before dispatch."
},
{
"type": "tool_call",
"toolName": "request_plan",
"content": "{\"teammate\":\"backend\",\"task\":\"Inspect the claimed authentication task and submit a plan before changing files.\"}",
"annotation": "The Lead delivers the plan request for the current assignment; the gate was already active before the teammate thread started."
},
{
"type": "system_event",
"content": "backend submit_plan -> plan_approval_request(request_id=req_000007, task_id=task_1712345678_0042)",
"annotation": "The request records the task and work version that the plan is meant to authorize."
"toolName": "connect_mcp",
"content": "{\"name\":\"deploy\"}",
"annotation": "External capabilities are added only when needed."
},
{
"type": "tool_call",
"toolName": "review_plan",
"content": "{\"request_id\":\"req_000007\",\"approve\":true,\"feedback\":\"Proceed with the scoped refactor.\"}",
"annotation": "Approval is correlated by request ID and cannot carry into a different assignment."
"toolName": "mcp__deploy__status",
"content": "{\"service\":\"web\"}",
"annotation": "Connecting discovers the tool; a separate call performs the status check."
},
{
"type": "tool_result",
"toolName": "mcp__deploy__status",
"content": "[deploy] web: running (v1.4.2)",
"annotation": "The readiness statement now comes from the MCP tool result rather than the connection event."
},
{
"type": "system_event",
"content": "plan_approval_response(request_id=req_000007, approve=true) -> backend",
"annotation": "The teammate receives the typed response before mutating tools are released."
},
{
"type": "system_event",
"content": "backend tool cwd -> .worktrees/auth-refactor",
"annotation": "Bash, read, and write derive their directory from the claimed task binding."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_1712345678_0042\"}",
"annotation": "Completing the first task makes its dependent test task ready."
},
{
"type": "system_event",
"content": "backend -> Lead: result(auth refactor complete) -> idle_notification",
"annotation": "The task directory stays selected through the completion turn, then IDLE releases the assignment."
},
{
"type": "system_event",
"content": "claim_next_task(tests) -> task_1712345678_0043; task_lock commits owner=tests",
"annotation": "An idle teammate discovers newly ready work without another direct assignment."
},
{
"type": "system_event",
"content": "tests -> Lead: result(test suite passed) -> idle_notification",
"annotation": "The runtime wakes the Lead when mailbox events arrive instead of asking the model to poll."
"content": "task_notification(status=completed): tests passed; teammate result and deploy status appended",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
},
{
"type": "assistant_text",
"content": "Authentication was refactored in its task-bound worktree and the dependent tests pass.",
"annotation": "The Lead combines parallel results into one user-facing outcome."
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The integrated harness returns a single user-facing outcome."
}
]
}

View File

@@ -1,46 +1,54 @@
{
"version": "s16",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"title": "Workflow Runtime",
"description": "A fixed review pipeline executes inside one Workflow call, records a journal, emits lifecycle and progress events, and returns one final tool result.",
"steps": [
{
"type": "user_message",
"content": "Search the documentation for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
"content": "Review this load_user change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"name\":\"docs\"}",
"annotation": "The runtime creates an MCP client for the named server."
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"args\":{\"budget\":null,\"changes\":\"def load_user(user_id):\\n query = f\\\"SELECT * FROM users WHERE id = {user_id}\\\"\\n return db.execute(query).fetchone()\\n\"}}",
"annotation": "The model selects a saved workflow and arguments; the host registry supplies its trusted metadata and script."
},
{
"type": "system_event",
"content": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
"content": "async_launched(runId=wf_review-changes_0000000000001a7b) -> task_started",
"annotation": "The runtime emits launch lifecycle events before it executes the script; this is not a tool result."
},
{
"type": "system_event",
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "system_event",
"content": "workflow_agent status=done -> journal append",
"annotation": "Every completed agent call is checkpointed as the script runs."
},
{
"type": "system_event",
"content": "task_notification(status=completed, outputFile=.runtime/wf_review-changes_0000000000001a7b.output.json)",
"annotation": "The task emits its final lifecycle event after output is written."
},
{
"type": "tool_result",
"toolName": "connect_mcp",
"content": "Connected to MCP server 'docs'. Discovered 2 tools: search, get_version",
"annotation": "Tool discovery expands the active tool pool."
"toolName": "Workflow",
"content": "{\"launched\":{\"status\":\"async_launched\",\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\"},\"result\":{\"confirmed\":[{\"dimension\":\"performance\",\"title\":\"audit:performance #1\",\"severity\":\"medium\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #2\",\"severity\":\"medium\"},{\"dimension\":\"style\",\"title\":\"audit:style #1\",\"severity\":\"medium\"},{\"dimension\":\"style\",\"title\":\"audit:style #2\",\"severity\":\"medium\"},{\"dimension\":\"security\",\"title\":\"audit:security #1\",\"severity\":\"low\"},{\"dimension\":\"security\",\"title\":\"audit:security #2\",\"severity\":\"low\"}]},\"task\":{\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\",\"status\":\"completed\",\"usage\":{\"agents\":11,\"tokens\":883},\"progress\":[{\"type\":\"workflow_phase\",\"title\":\"Review\"},{\"type\":\"workflow_agent\",\"label\":\"audit:correctness\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_phase\",\"title\":\"Verify\"},{\"type\":\"workflow_agent\",\"label\":\"audit:security\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:performance\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:style\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:correctness:audit:correctness #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_log\",\"message\":\"confirmed 6 real finding(s)\"}]}}",
"annotation": "The demo fixture returns six synthetic findings and measured runner usage; these are not claims about the repository."
},
{
"type": "tool_call",
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[docs] Found 3 results for 'deployment'",
"annotation": "The external result is appended like any other tool result."
},
{
"type": "assistant_text",
"content": "The docs server found three matches for deployment guidance.",
"annotation": "The agent summarizes external tool output for the user."
"type": "system_event",
"content": "append Workflow tool_result -> messages[]",
"annotation": "A main-loop integration can append this JSON-safe result and continue with the updated conversation."
}
]
}

View File

@@ -1,102 +1,49 @@
{
"version": "s17",
"title": "Integrated Harness",
"description": "The harness composes context assembly, tools, memory, teams, background work, cron, worktrees, and MCP.",
"title": "Goal Loop",
"description": "A separate evaluator reads the conversation at the end of a turn and sends unfinished work back through the same loop.",
"steps": [
{
"type": "user_message",
"content": "Prepare this project for release. Check the code, update the docs, and report deployment readiness.",
"annotation": "One ordinary request needs several earlier capabilities to work together."
},
{
"type": "system_event",
"content": "assemble_prompt: memory + task graph + skills + available tools + policy",
"annotation": "The runtime builds the prompt from layered sources of context."
"content": "/goal pytest tests/auth exits with code 0",
"annotation": "The command stores an active completion condition and starts the work."
},
{
"type": "assistant_text",
"content": "I suggest a docs teammate while I run the release checks and inspect deployment status. Shall I start that team?",
"annotation": "The Lead proposes the team before adding another persistent agent."
"content": "The authentication code looks correct. The tests should pass now.",
"annotation": "With no more tool calls, the session asks the evaluator whether the active goal is complete."
},
{
"type": "user_message",
"content": "Yes. Start the docs teammate and continue.",
"annotation": "User confirmation opens the team boundary inherited from S15."
"type": "system_event",
"content": "goal_evaluated ok=false -> block",
"annotation": "The evaluator finds no test exit code in the conversation."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"code-review\"}",
"annotation": "Skills contribute procedural context before execution."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update release notes\",\"description\":\"Prepare release documentation and report the result.\"}",
"annotation": "The shared task board gives the docs work a stable owner and lifecycle."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0042: Update release notes",
"annotation": "The task ID connects the assignment to its working directory."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"name\":\"release-docs\",\"task_id\":\"task_1712345678_0042\"}",
"annotation": "The pending docs task receives a separate checkout before it is claimed."
},
{
"type": "tool_result",
"toolName": "create_worktree",
"content": "Worktree 'release-docs' created for task_1712345678_0042",
"annotation": "The task now carries the checkout used by its eventual owner."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"docs\",\"role\":\"documentation engineer\",\"prompt\":\"Claim task_1712345678_0042, update the release notes in its task-bound worktree, and report the result.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
"type": "system_event",
"content": "[Goal still active] Run pytest tests/auth and surface the exit code.",
"annotation": "The controller appends the reason to messages[] and continues the same loop; no queue is involved."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "{\"command\":\"python -m unittest tests.test_agent_teams_runtime\",\"run_in_background\":true}",
"annotation": "Long-running validation goes through the background task path."
},
{
"type": "system_event",
"content": "permission: user approved the exact test command",
"annotation": "Team confirmation does not authorize shell execution; the foreground turn asks separately before dispatch."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"name\":\"deploy\"}",
"annotation": "External capabilities are added only when needed."
},
{
"type": "tool_call",
"toolName": "mcp__deploy__status",
"content": "{\"service\":\"web\"}",
"annotation": "Connecting discovers the tool; a separate call performs the status check."
"content": "pytest tests/auth",
"annotation": "The next agent turn runs the missing check."
},
{
"type": "tool_result",
"toolName": "mcp__deploy__status",
"content": "[deploy] web: running (v1.4.2)",
"annotation": "The readiness statement now comes from the MCP tool result rather than the connection event."
},
{
"type": "system_event",
"content": "task_notification(status=completed): tests passed; teammate result and deploy status appended",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
"toolName": "bash",
"content": "exit_code=0\n12 passed in 0.42s",
"annotation": "The concrete command result enters the same conversation."
},
{
"type": "assistant_text",
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The integrated harness returns a single user-facing outcome."
"content": "pytest tests/auth exited 0: 12 tests passed.",
"annotation": "A turn with no further tool call reaches the Stop hook again."
},
{
"type": "system_event",
"content": "goal_evaluated ok=true -> achieved",
"annotation": "The controller records success, clears the active goal, and returns."
}
]
}

View File

@@ -1,54 +0,0 @@
{
"version": "s18",
"title": "Workflow Runtime",
"description": "A fixed review pipeline executes inside one Workflow call, records a journal, emits lifecycle and progress events, and returns one final tool result.",
"steps": [
{
"type": "user_message",
"content": "Review this change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
},
{
"type": "tool_call",
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"args\":{\"budget\":null}}",
"annotation": "The model selects a saved workflow and arguments; the host registry supplies its trusted metadata and script."
},
{
"type": "system_event",
"content": "async_launched(runId=wf_review-changes_0000000000001a7b) -> task_started",
"annotation": "The runtime emits launch lifecycle events before it executes the script; this is not a tool result."
},
{
"type": "system_event",
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "system_event",
"content": "workflow_agent status=done -> journal append",
"annotation": "Every completed agent call is checkpointed as the script runs."
},
{
"type": "system_event",
"content": "task_notification(status=completed, outputFile=.runtime/wf_review-changes_0000000000001a7b.output.json)",
"annotation": "The task emits its final lifecycle event after output is written."
},
{
"type": "tool_result",
"toolName": "Workflow",
"content": "{\"launched\":{\"status\":\"async_launched\",\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\"},\"result\":{\"confirmed\":[{\"dimension\":\"security\",\"title\":\"audit:security #1\",\"severity\":\"high\"},{\"dimension\":\"style\",\"title\":\"audit:style #1\",\"severity\":\"high\"},{\"dimension\":\"security\",\"title\":\"audit:security #2\",\"severity\":\"medium\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #2\",\"severity\":\"medium\"},{\"dimension\":\"correctness\",\"title\":\"audit:correctness #1\",\"severity\":\"low\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #1\",\"severity\":\"low\"}]},\"task\":{\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\",\"status\":\"completed\",\"usage\":{\"agents\":11,\"tokens\":352},\"progress\":[{\"type\":\"workflow_phase\",\"title\":\"Review\"},{\"type\":\"workflow_agent\",\"label\":\"audit:correctness\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_phase\",\"title\":\"Verify\"},{\"type\":\"workflow_agent\",\"label\":\"audit:security\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:performance\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:style\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:correctness:audit:correctness #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_log\",\"message\":\"confirmed 6 real finding(s)\"}]}}",
"annotation": "The deterministic sample returns its six fixture findings and measured runner usage; these are not claims about the repository."
},
{
"type": "system_event",
"content": "append Workflow tool_result -> messages[]",
"annotation": "A main-loop integration can append this JSON-safe result and continue with the updated conversation."
}
]
}

View File

@@ -1,49 +0,0 @@
{
"version": "s19",
"title": "Goal Loop",
"description": "A separate evaluator reads the conversation at the end of a turn and sends unfinished work back through the same loop.",
"steps": [
{
"type": "user_message",
"content": "/goal pytest tests/auth exits with code 0",
"annotation": "The command stores an active completion condition and starts the work."
},
{
"type": "assistant_text",
"content": "The authentication code looks correct. The tests should pass now.",
"annotation": "With no more tool calls, the session asks the evaluator whether the active goal is complete."
},
{
"type": "system_event",
"content": "goal_evaluated ok=false -> block",
"annotation": "The evaluator finds no test exit code in the conversation."
},
{
"type": "system_event",
"content": "[Goal still active] Run pytest tests/auth and surface the exit code.",
"annotation": "The controller appends the reason to messages[] and continues the same loop; no queue is involved."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "pytest tests/auth",
"annotation": "The next agent turn runs the missing check."
},
{
"type": "tool_result",
"toolName": "bash",
"content": "exit_code=0\n12 passed in 0.42s",
"annotation": "The concrete command result enters the same conversation."
},
{
"type": "assistant_text",
"content": "pytest tests/auth exited 0: 12 tests passed.",
"annotation": "A turn with no further tool call reaches the Stop hook again."
},
{
"type": "system_event",
"content": "goal_evaluated ok=true -> achieved",
"annotation": "The controller records success, clears the active goal, and returns."
}
]
}

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time" },
"nav": { "home": "Home", "timeline": "Timeline", "compare": "Compare", "layers": "Layers", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time", "start": "Start Learning", "core_pattern": "The Core Pattern", "core_pattern_desc": "Every AI coding agent shares the same loop: call the model, execute tools, feed results back. The harness adds policy, permissions, memory, coordination, and lifecycle control around it.", "learning_path": "Learning Path", "learning_path_desc": "19 progressive sessions, from a simple loop to deterministic orchestration and goal closure", "layers_title": "Architectural Layers", "layers_desc": "Five orthogonal concerns that compose into a complete agent", "loc": "LOC", "learn_more": "Learn More", "versions_in_layer": "versions", "message_flow": "Message Growth", "message_flow_desc": "Watch the messages array grow as the agent loop executes" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time", "start": "Start Learning", "core_pattern": "The Core Pattern", "core_pattern_desc": "Every AI coding agent shares the same loop: call the model, execute tools, feed results back. The harness adds policy, permissions, memory, coordination, and lifecycle control around it.", "learning_path": "Learning Path", "learning_path_desc": "17 progressive sessions, from a simple loop to deterministic orchestration and goal closure", "layers_title": "Architectural Layers", "layers_desc": "Five orthogonal concerns that compose into a complete agent", "loc": "LOC", "learn_more": "Learn More", "versions_in_layer": "versions", "message_flow": "Message Growth", "message_flow_desc": "Watch the messages array grow as the agent loop executes" },
"version": { "loc": "lines of code", "tools": "tools", "new": "New", "prev": "Previous", "next": "Next", "view_source": "View Source", "view_diff": "View Diff", "design_decisions": "Design Decisions", "whats_new": "What's New", "tutorial": "Tutorial", "simulator": "Agent Loop Simulator", "execution_flow": "Execution Flow", "architecture": "Architecture", "concept_viz": "Concept Visualization", "alternatives": "Alternatives Considered", "tab_learn": "Learn", "tab_simulate": "Simulate", "tab_code": "Code", "tab_deep_dive": "Deep Dive" },
"sim": { "play": "Play", "pause": "Pause", "step": "Step", "reset": "Reset", "speed": "Speed", "step_of": "of" },
"timeline": { "title": "Learning Path", "subtitle": "s01 to s19: Progressive Agent Harness Design", "layer_legend": "Layer Legend", "loc_growth": "LOC Growth", "learn_more": "Learn More" },
"timeline": { "title": "Learning Path", "subtitle": "s01 to s17: Progressive Agent Harness Design", "layer_legend": "Layer Legend", "loc_growth": "LOC Growth", "learn_more": "Learn More" },
"layers": {
"title": "Architectural Layers",
"subtitle": "Five orthogonal concerns that compose into a complete agent",
@@ -48,16 +48,14 @@
"s07": "Skills",
"s08": "Context Compact",
"s09": "Memory",
"s10": "Context Assembly",
"s11": "Error Recovery",
"s12": "Task System",
"s13": "Background Tasks",
"s14": "Cron Scheduler",
"s15": "Agent Team Runtime",
"s16": "MCP Tools",
"s17": "Integrated Harness",
"s18": "Workflow Runtime",
"s19": "Goal Loop"
"s10": "Task System",
"s11": "Background Tasks",
"s12": "Cron Scheduler",
"s13": "Agent Team Runtime",
"s14": "MCP Tools",
"s15": "Integrated Harness",
"s16": "Workflow Runtime",
"s17": "Goal Loop"
},
"layer_labels": {
"tools": "Tools & Execution",
@@ -76,15 +74,13 @@
"s07": "On-Demand Skill Loading",
"s08": "Three-Layer Context Compression",
"s09": "Memory Library",
"s10": "Runtime Context Assembly",
"s11": "Error Recovery Paths",
"s12": "Task Board Dependencies",
"s13": "Background Task Lanes",
"s14": "Cron Scheduler",
"s15": "Team Runtime: Message, Claim, Bind",
"s16": "MCP Tool Bridge",
"s17": "Integrated Harness Turn",
"s18": "Workflow Runtime",
"s19": "Goal Completion Gate"
"s10": "Task Board Dependencies",
"s11": "Background Task Lanes",
"s12": "Cron Scheduler",
"s13": "Team Runtime: Message, Claim, Bind",
"s14": "MCP Tool Bridge",
"s15": "Integrated Harness Turn",
"s16": "Workflow Runtime",
"s17": "Goal Completion Gate"
}
}

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加" },
"nav": { "home": "ホーム", "timeline": "学習パス", "compare": "バージョン比較", "layers": "アーキテクチャ層", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加", "start": "学習を始める", "core_pattern": "コアパターン", "core_pattern_desc": "すべての AI コーディングエージェントは同じループを共有するモデルを呼び出し、ツールを実行し、結果を返す。Harness はその周囲にポリシー、権限、記憶、協調、ライフサイクル制御を加える。", "learning_path": "学習パス", "learning_path_desc": "19の段階的セッション、シンプルなループから決定的な編成と目標完了まで", "layers_title": "アーキテクチャ層", "layers_desc": "5つの直交する関心事が完全なエージェントを構成", "loc": "行", "learn_more": "詳細を見る", "versions_in_layer": "バージョン", "message_flow": "メッセージの増加", "message_flow_desc": "エージェントループ実行時のメッセージ配列の成長を観察" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加", "start": "学習を始める", "core_pattern": "コアパターン", "core_pattern_desc": "すべての AI コーディングエージェントは同じループを共有するモデルを呼び出し、ツールを実行し、結果を返す。Harness はその周囲にポリシー、権限、記憶、協調、ライフサイクル制御を加える。", "learning_path": "学習パス", "learning_path_desc": "17の段階的セッション、シンプルなループから決定的な編成と目標完了まで", "layers_title": "アーキテクチャ層", "layers_desc": "5つの直交する関心事が完全なエージェントを構成", "loc": "行", "learn_more": "詳細を見る", "versions_in_layer": "バージョン", "message_flow": "メッセージの増加", "message_flow_desc": "エージェントループ実行時のメッセージ配列の成長を観察" },
"version": { "loc": "行のコード", "tools": "ツール", "new": "新規", "prev": "前のバージョン", "next": "次のバージョン", "view_source": "ソースを見る", "view_diff": "差分を見る", "design_decisions": "設計判断", "whats_new": "新機能", "tutorial": "チュートリアル", "simulator": "エージェントループシミュレーター", "execution_flow": "実行フロー", "architecture": "アーキテクチャ", "concept_viz": "コンセプト可視化", "alternatives": "検討された代替案", "tab_learn": "学習", "tab_simulate": "シミュレーション", "tab_code": "ソースコード", "tab_deep_dive": "詳細分析" },
"sim": { "play": "再生", "pause": "一時停止", "step": "ステップ", "reset": "リセット", "speed": "速度", "step_of": "/" },
"timeline": { "title": "学習パス", "subtitle": "s01からs19へ:段階的エージェント Harness 設計", "layer_legend": "レイヤー凡例", "loc_growth": "コード量の推移", "learn_more": "詳細を見る" },
"timeline": { "title": "学習パス", "subtitle": "s01からs17へ:段階的エージェント Harness 設計", "layer_legend": "レイヤー凡例", "loc_growth": "コード量の推移", "learn_more": "詳細を見る" },
"layers": {
"title": "アーキテクチャ層",
"subtitle": "5つの直交する関心事が完全なエージェントを構成",
@@ -48,16 +48,14 @@
"s07": "スキル",
"s08": "コンテキスト圧縮",
"s09": "メモリ",
"s10": "コンテキスト組み立て",
"s11": "エラー回復",
"s12": "タスクシステム",
"s13": "バックグラウンドタスク",
"s14": "Cron スケジューラー",
"s15": "Agent Team Runtime",
"s16": "MCP ツール",
"s17": "Integrated Harness",
"s18": "Workflow Runtime",
"s19": "Goal Loop"
"s10": "タスクシステム",
"s11": "バックグラウンドタスク",
"s12": "Cron スケジューラー",
"s13": "Agent Team Runtime",
"s14": "MCP ツール",
"s15": "Integrated Harness",
"s16": "Workflow Runtime",
"s17": "Goal Loop"
},
"layer_labels": {
"tools": "ツールと実行",
@@ -76,15 +74,13 @@
"s07": "オンデマンド スキルローディング",
"s08": "3層コンテキスト圧縮",
"s09": "メモリライブラリ",
"s10": "実行時コンテキスト組み立て",
"s11": "エラー回復経路",
"s12": "タスクボード依存関係",
"s13": "バックグラウンドタスクレーン",
"s14": "Cron スケジューラー",
"s15": "Team Runtimeメッセージ・認領・ディレクトリ紐付け",
"s16": "MCP ツールブリッジ",
"s17": "Integrated Harness のターン",
"s18": "Workflow Runtime",
"s19": "目標完了ゲート"
"s10": "タスクボード依存関係",
"s11": "バックグラウンドタスクレーン",
"s12": "Cron スケジューラー",
"s13": "Team Runtimeメッセージ・認領・ディレクトリ紐付け",
"s14": "MCP ツールブリッジ",
"s15": "Integrated Harness のターン",
"s16": "Workflow Runtime",
"s17": "目標完了ゲート"
}
}

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制" },
"nav": { "home": "首页", "timeline": "学习路径", "compare": "版本对比", "layers": "架构层", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制", "start": "开始学习", "core_pattern": "核心模式", "core_pattern_desc": "所有 AI 编程 Agent 共享同一个循环调用模型、执行工具、回传结果。Harness 在循环周围加入策略、权限、记忆、协作与生命周期控制。", "learning_path": "学习路径", "learning_path_desc": "19 个渐进式课程,从简单循环到确定性编排与目标闭环", "layers_title": "架构层次", "layers_desc": "五个正交关注点组合成完整的 Agent", "loc": "行", "learn_more": "了解更多", "versions_in_layer": "个版本", "message_flow": "消息增长", "message_flow_desc": "观察 Agent 循环执行时消息数组的增长" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制", "start": "开始学习", "core_pattern": "核心模式", "core_pattern_desc": "所有 AI 编程 Agent 共享同一个循环调用模型、执行工具、回传结果。Harness 在循环周围加入策略、权限、记忆、协作与生命周期控制。", "learning_path": "学习路径", "learning_path_desc": "17 个渐进式课程,从简单循环到确定性编排与目标闭环", "layers_title": "架构层次", "layers_desc": "五个正交关注点组合成完整的 Agent", "loc": "行", "learn_more": "了解更多", "versions_in_layer": "个版本", "message_flow": "消息增长", "message_flow_desc": "观察 Agent 循环执行时消息数组的增长" },
"version": { "loc": "行代码", "tools": "个工具", "new": "新增", "prev": "上一版", "next": "下一版", "view_source": "查看源码", "view_diff": "查看变更", "design_decisions": "设计决策", "whats_new": "新增内容", "tutorial": "教程", "simulator": "Agent 循环模拟器", "execution_flow": "执行流程", "architecture": "架构", "concept_viz": "概念可视化", "alternatives": "替代方案", "tab_learn": "学习", "tab_simulate": "模拟", "tab_code": "源码", "tab_deep_dive": "深入探索" },
"sim": { "play": "播放", "pause": "暂停", "step": "单步", "reset": "重置", "speed": "速度", "step_of": "/" },
"timeline": { "title": "学习路径", "subtitle": "s01 到 s19:渐进式 Agent Harness 设计", "layer_legend": "层次图例", "loc_growth": "代码量增长", "learn_more": "了解更多" },
"timeline": { "title": "学习路径", "subtitle": "s01 到 s17:渐进式 Agent Harness 设计", "layer_legend": "层次图例", "loc_growth": "代码量增长", "learn_more": "了解更多" },
"layers": {
"title": "架构层次",
"subtitle": "五个正交关注点组合成完整的 Agent",
@@ -48,16 +48,14 @@
"s07": "Skills",
"s08": "Context Compact",
"s09": "Memory",
"s10": "Context Assembly",
"s11": "Error Recovery",
"s12": "Task System",
"s13": "Background Tasks",
"s14": "Cron Scheduler",
"s15": "Agent Team Runtime",
"s16": "MCP Tools",
"s17": "Agent Harness 集成",
"s18": "Workflow Runtime",
"s19": "Goal Loop"
"s10": "Task System",
"s11": "Background Tasks",
"s12": "Cron Scheduler",
"s13": "Agent Team Runtime",
"s14": "MCP Tools",
"s15": "Agent Harness 集成",
"s16": "Workflow Runtime",
"s17": "Goal Loop"
},
"layer_labels": {
"tools": "工具与执行",
@@ -76,15 +74,13 @@
"s07": "On-Demand Skill Loading",
"s08": "Three-Layer Context Compact",
"s09": "记忆图书馆",
"s10": "运行时上下文组装",
"s11": "Error Recovery Paths",
"s12": "任务看板依赖",
"s13": "Background Task Lanes",
"s14": "Cron Scheduler",
"s15": "团队运行时:消息、认领与目录绑定",
"s16": "MCP Tool Bridge",
"s17": "Agent Harness 集成流程",
"s18": "Workflow Runtime",
"s19": "目标完成闸门"
"s10": "任务看板依赖",
"s11": "Background Task Lanes",
"s12": "Cron Scheduler",
"s13": "团队运行时:消息、认领与目录绑定",
"s14": "MCP Tool Bridge",
"s15": "Agent Harness 集成流程",
"s16": "Workflow Runtime",
"s17": "目标完成闸门"
}
}

View File

@@ -18,8 +18,6 @@ export const VERSION_ORDER = [
"s15",
"s16",
"s17",
"s18",
"s19",
] as const;
export const LEARNING_PATH = VERSION_ORDER;
@@ -107,84 +105,68 @@ export const VERSION_META: Record<string, {
prevVersion: "s08",
},
s10: {
title: "Context Assembly",
subtitle: "Build Model Input from Runtime State",
coreAddition: "Runtime context assembly",
keyInsight: "Stable instructions and dynamic state should be assembled deliberately at the model boundary.",
layer: "planning",
prevVersion: "s09",
},
s11: {
title: "Error Recovery",
subtitle: "Errors Are the Start of a Retry",
coreAddition: "Retry strategy",
keyInsight: "A robust harness classifies failures and decides what kind of retry is worthwhile.",
layer: "planning",
prevVersion: "s10",
},
s12: {
title: "Task System",
subtitle: "Break Big Goals into Small Tasks",
coreAddition: "Task board",
keyInsight: "A task graph turns vague goals into ordered, observable work.",
layer: "collaboration",
prevVersion: "s11",
prevVersion: "s09",
},
s13: {
s11: {
title: "Background Tasks",
subtitle: "Slow Operations Go to the Background",
coreAddition: "Background execution",
keyInsight: "The agent can keep reasoning while slow work completes elsewhere.",
layer: "concurrency",
prevVersion: "s12",
prevVersion: "s10",
},
s14: {
s12: {
title: "Cron Scheduler",
subtitle: "Producing Work on a Schedule",
coreAddition: "Scheduled task creation",
keyInsight: "Recurring work should be created by the harness, not remembered by the model.",
layer: "concurrency",
prevVersion: "s13",
prevVersion: "s11",
},
s15: {
s13: {
title: "Agent Team Runtime",
subtitle: "Persistent Teammates, Atomic Claims, Task-Bound Worktrees",
coreAddition: "Team runtime with task-bound worktrees",
keyInsight: "Persistent teammates can reliably discover and execute parallel work when the runtime owns messaging, atomic claims, and task-bound working directories.",
layer: "collaboration",
prevVersion: "s14",
prevVersion: "s12",
},
s16: {
s14: {
title: "MCP Tools",
subtitle: "External Tools, Standard Protocol",
coreAddition: "MCP tool bridge",
keyInsight: "External services can become agent tools through a standard discovery and call protocol.",
layer: "collaboration",
prevVersion: "s15",
prevVersion: "s13",
},
s17: {
s15: {
title: "Integrated Harness",
subtitle: "Many Mechanisms, One Loop",
coreAddition: "Integrated harness",
keyInsight: "The integrated harness is still one loop, surrounded by the systems introduced across the course.",
layer: "collaboration",
prevVersion: "s16",
prevVersion: "s14",
},
s18: {
s16: {
title: "Workflow Runtime",
subtitle: "Scripts Own Fixed Orchestration",
coreAddition: "Resumable workflow runtime",
keyInsight: "When orchestration has a fixed shape, code can make it parallel, deterministic, and resumable.",
layer: "concurrency",
prevVersion: "s17",
prevVersion: "s15",
},
s19: {
s17: {
title: "Goal Loop",
subtitle: "Independent Evaluation Decides When to Stop",
coreAddition: "Goal completion gate",
keyInsight: "A durable goal keeps the loop working until an independent evaluator finds the completion condition satisfied in the conversation.",
layer: "planning",
prevVersion: "s18",
prevVersion: "s16",
},
};
@@ -199,7 +181,7 @@ export const LAYERS = [
id: "planning" as const,
label: "Planning & Control",
color: "#10B981",
versions: ["s05", "s06", "s07", "s10", "s11", "s19"],
versions: ["s05", "s06", "s07", "s17"],
},
{
id: "memory" as const,
@@ -211,12 +193,12 @@ export const LAYERS = [
id: "concurrency" as const,
label: "Concurrency & Scheduling",
color: "#F59E0B",
versions: ["s13", "s14", "s18"],
versions: ["s11", "s12", "s16"],
},
{
id: "collaboration" as const,
label: "Multi-Agent Platform",
color: "#EF4444",
versions: ["s12", "s15", "s16", "s17"],
versions: ["s10", "s13", "s14", "s15"],
},
] as const;