130 lines
5.8 KiB
HTML
130 lines
5.8 KiB
HTML
<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> |