Tools
Belvedir
Zero-dependency OpenClaw plugin: send traces and conversations to Belvedir
Install
openclaw plugins install https://github.com/Belvedir/openclaw-belvedir
Configuration Example
{
"plugins": {
"allow": ["belvedir"],
"entries": {
"belvedir": {
"enabled": true,
"config": { "apiKey": "bv_live_..." },
"hooks": { "allowConversationAccess": true }
}
}
}
}
README
# openclaw-belvedir
Send [OpenClaw](https://openclaw.ai) traces and conversations to [Belvedir](https://platform.belvedir.ai): sessions, task segmentation, and grouping over your agent's production traffic.
**Zero dependencies.** The plugin consumes OpenClaw's typed plugin hooks and posts OTLP JSON to Belvedir's ingest endpoint with Node's built-ins (`fetch`, `node:zlib`, `node:crypto`) — no OpenTelemetry SDK, no packages to install, no dependency tree for a security scanner to flag. It is plain JavaScript: what you review is exactly what runs. See [SECURITY.md](SECURITY.md).
**Real sessions.** OpenClaw's stock OTel exporter deliberately omits session ids, so each agent turn lands as its own session. This plugin reads OpenClaw's real session identity from the hook context: a multi-turn conversation becomes one Belvedir session and segments into tasks properly. It also skips the ~13 single-span housekeeping traces per turn the stock exporter emits.
## Install
```bash
openclaw plugins install https://github.com/Belvedir/openclaw-belvedir
```
Create an API key at platform.belvedir.ai under your project's API keys, then in `~/.openclaw/openclaw.json`:
```json
{
"plugins": {
"allow": ["belvedir"],
"entries": {
"belvedir": {
"enabled": true,
"config": { "apiKey": "bv_live_..." },
"hooks": { "allowConversationAccess": true }
}
}
}
}
```
`hooks.allowConversationAccess` is OpenClaw's consent gate: non-bundled plugins cannot see prompt/response content without the operator granting it explicitly. Without it the plugin still runs but captures structure and timing only. Restart the gateway (`openclaw gateway restart`) to load the plugin.
## Configuration
Environment variables win; the `config` object in `openclaw.json` fills the gaps.
| Env var | config key | Default | Meaning |
|---|---|---|---|
| `BELVEDIR_API_KEY` | `apiKey` | — (required) | Project API key (`bv_live_...`) |
| `BELVEDIR_ENDPOINT` | `endpoint` | `https://platform.belvedir.ai/api/v1/traces` | Ingest endpoint |
| `BELVEDIR_PRIVACY_MODE` | `privacyMode` | `false` | Strip prompt/response/tool content; keep models, usage, structure |
| `BELVEDIR_CAPTURE_SENDER` | `captureSender` | `false` | Stamp the channel sender id as `user.id` |
| `BELVEDIR_DEBUG` | `debug` | `false` | Log hook firings and exports to the gateway log |
Full prompts and responses are captured by default (Belvedir segments sessions from the actual conversation; clipped content means worse tasks). Use privacy mode to send only metadata.
## What gets captured
One agent turn becomes one trace:
- **agent** — the turn root: session id, model, channel, run outcome.
- **chat \<model\>** — the conversation the model saw (`gen_ai.input.messages`, with OpenClaw's tool-call blocks normalized to tool_call parts), its reply (`gen_ai.output.messages`), and token usage including cache reads/writes.
- **api \<model\>** — one span per provider request: timing, outcome, error category on failure.
- **tool: \<name\>** — tool calls with arguments and results.
## Verify your setup
```bash
BELVEDIR_API_KEY=bv_live_... node tests/simulate-run.js
```
fires the exact hook sequence of a real two-turn session and prints the session id; it should appear under your project's Data pages within a few seconds. `node tests/test-offline.js` is the self-contained test CI runs.
## Failure behavior
Telemetry never blocks or crashes the agent: all hooks are observation-only, exports buffer in memory and flush when a turn ends, a failed export retries once then drops the batch with a log line, and a `401`/`402` disables the exporter for the rest of the process instead of spamming. OpenClaw fires observation hooks in parallel, so `llm_output` for the final model call can land a few milliseconds *after* `agent_end`; the plugin holds each turn open briefly to catch those stragglers.
## License
Apache-2.0
tools
Comments
Sign in to leave a comment