This commit is contained in:
2026-04-10 19:00:38 -04:00
parent b8996d2ecb
commit 2c976bb75b
10 changed files with 957 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
<h2>Transport Layer</h2>
<p class="subtitle">Tool Registration, Request/Response Contracts & Error Normalization</p>
<div class="section">
<h3>Tool Registration Flow</h3>
<div class="mockup">
<div class="mockup-header">Plugin Lifecycle: Install → Register → Serve</div>
<div class="mockup-body" style="font-family: monospace; font-size: 13px; line-height: 1.8; padding: 16px;">
<div style="color: #53a8b6;">1. INSTALL</div>
<div style="color: #eee; margin-left: 16px;">openclaw plugins install clawhub:obsidian-rag</div>
<div style="color: #888; margin-left: 16px;">→ Downloads plugin, reads openclaw.plugin.json</div>
<div style="color: #53a8b6; margin-top: 12px;">2. REGISTER</div>
<div style="color: #eee; margin-left: 16px;">Plugin.register(tools) → OpenClaw Tool Registry</div>
<div style="color: #888; margin-left: 16px;">→ 4 tools registered: search, index, status, memory_store</div>
<div style="color: #888; margin-left: 16px;">→ Each tool declares: name, description, parameterSchema, requiredPermissions</div>
<div style="color: #53a8b6; margin-top: 12px;">3. SERVE</div>
<div style="color: #eee; margin-left: 16px;">OpenClaw Agent → tool_call(obsidian_rag_search, {query: "..."}) → Plugin</div>
<div style="color: #eee; margin-left: 16px;">Plugin → structured response → OpenClaw Agent</div>
<div style="color: #53a8b6; margin-top: 12px;">4. HEALTH CHECK</div>
<div style="color: #eee; margin-left: 16px;">Plugin.onLoad() → probe Ollama, probe LanceDB, probe Vault</div>
<div style="color: #eee; margin-left: 16px;">→ Reports status: healthy | degraded | unavailable</div>
</div>
</div>
</div>
<div class="section" style="margin-top: 20px;">
<h3>Standardized Response Envelope</h3>
<div class="mockup">
<div class="mockup-header">All tool responses use this envelope</div>
<div class="mockup-body" style="font-family: monospace; font-size: 12px; line-height: 1.5; padding: 16px; background: #0d1117; color: #c9d1d9;">
<pre style="margin: 0;">{
"status": "healthy" | "degraded" | "unavailable",
"data": T | null,
"error": {
"code": string, // e.g. "OLLAMA_UNREACHABLE"
"message": string, // human-readable
"recoverable": bool, // can the agent retry?
"suggestion": string // e.g. "Run obsidian-rag index first"
} | null,
"meta": {
"query_time_ms": number,
"chunks_scanned": number,
"index_version": string,
"vault_mtime": string // ISO 8601
}
}</pre>
</div>
</div>
</div>
<div class="section" style="margin-top: 20px;">
<h3>Error Normalization Matrix</h3>
<div class="mockup">
<div class="mockup-header">How each failure maps to status + error</div>
<div class="mockup-body" style="font-family: monospace; font-size: 12px; padding: 16px;">
<table style="width: 100%; border-collapse: collapse; color: #eee;">
<thead>
<tr style="border-bottom: 2px solid #53a8b6;">
<th style="text-align: left; padding: 6px;">Failure</th>
<th style="text-align: left; padding: 6px;">Status</th>
<th style="text-align: left; padding: 6px;">Code</th>
<th style="text-align: left; padding: 6px;">Recoverable</th>
</tr>
</thead>
<tbody>
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 6px;">Ollama down</td>
<td style="padding: 6px; color: #f0a500;">degraded</td>
<td style="padding: 6px;">OLLAMA_UNREACHABLE</td>
<td style="padding: 6px;">yes — retry after start</td>
</tr>
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 6px;">Empty vault / no index</td>
<td style="padding: 6px; color: #e94560;">unavailable</td>
<td style="padding: 6px;">INDEX_NOT_FOUND</td>
<td style="padding: 6px;">yes — run index first</td>
</tr>
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 6px;">LanceDB corrupted</td>
<td style="padding: 6px; color: #e94560;">unavailable</td>
<td style="padding: 6px;">INDEX_CORRUPTED</td>
<td style="padding: 6px;">yes — run reindex</td>
</tr>
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 6px;">Path traversal attempt</td>
<td style="padding: 6px; color: #e94560;">unavailable</td>
<td style="padding: 6px;">SECURITY_VIOLATION</td>
<td style="padding: 6px;">no</td>
</tr>
<tr style="border-bottom: 1px solid #333;">
<td style="padding: 6px;">Sensitive content blocked</td>
<td style="padding: 6px; color: #f0a500;">degraded</td>
<td style="padding: 6px;">SENSITIVE_FILTERED</td>
<td style="padding: 6px;">yes — with confirmation</td>
</tr>
<tr>
<td style="padding: 6px;">Indexer CLI crash</td>
<td style="padding: 6px; color: #e94560;">unavailable</td>
<td style="padding: 6px;">INDEXER_FAILED</td>
<td style="padding: 6px;">yes — retry once</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="section" style="margin-top: 20px;">
<h3>Key Design Points</h3>
<div class="pros-cons">
<div class="pros"><h4>Why this works</h4>
<ul>
<li>OpenClaw agent never sees raw exceptions — all errors normalized</li>
<li>Three-state health (healthy/degraded/unavailable) lets agent adapt behavior</li>
<li>Recoverable flag lets agent decide whether to retry or inform user</li>
<li>Suggestion field gives agent context to offer remediation</li>
</ul>
</div>
<div class="cons"><h4>Trade-offs</h4>
<ul>
<li>Envelope adds ~200 bytes per response (negligible)</li>
<li>Agent must handle three status states, not just success/fail</li>
<li>Health check on load adds ~1s startup latency</li>
</ul>
</div>
</div>
</div>