@senpi-ai/runtime
v1.1.1
Published
Senpi runtime plugin for OpenClaw
Downloads
1,026
Keywords
Readme
@senpi-ai/runtime
Event-driven automated trading plugin for OpenClaw. Orchestrates scanners, LLM-based trade decisions, and a DSL trailing stop-loss exit engine.
Prerequisites
- OpenClaw >= 2026.2.0
- Node >= 22
- Senpi API key (for live trading)
Install
openclaw plugins install @senpi-ai/runtimeCustom installs (Git checkout, dist/-only copy, or Docker without devDependencies): run npm install in the package root (or npm ci --omit=dev from a lockfile) so node_modules includes runtime dependencies. The runtime uses TypeBox at load time for scanner option validation (@sinclair/typebox / @sinclair/typebox/value); if that package is missing, the gateway will fail to load the plugin with Cannot find module '@sinclair/typebox/value'.
Configure
Add the plugin to your OpenClaw config (e.g. ~/.openclaw/openclaw.json or via openclaw config set). Use the plugin id @senpi-ai/runtime as the key:
{
"plugins": {
"entries": {
"@senpi-ai/runtime": {
"enabled": true,
"config": {
"stateDir": "~/.openclaw/senpi-state",
"apiKey": "YOUR_SENPI_API_KEY",
"logLevel": "info"
}
}
}
}
}Log level
The runtime's minimum log level defaults to info. Accepted values are debug, info, warn, and error (case-insensitive); anything else falls back to info with a one-time console warning at startup.
Resolution order (highest priority first):
- Plugin config
logLevel— set it inside the pluginconfigblock inopenclaw.json. This is the recommended place so the level lives next to the rest of the runtime's configuration and survives gateway restarts without shell env wiring. SENPI_LOG_LEVELenv var — useful for one-off overrides or when running the gateway under Docker Compose where env vars are easier to inject than config patches.- Default —
info.
// ~/.openclaw/openclaw.json
{
"plugins": {
"entries": {
"@senpi-ai/runtime": {
"enabled": true,
"config": {
"logLevel": "debug"
}
}
}
}
}# Env-var alternative (ignored if plugin config logLevel is set)
export SENPI_LOG_LEVEL=warnThe runtime logs the resolved level and its source on plugin start:
[senpi-runtime] log level: info (source: default). Set plugin config "logLevel" or env SENPI_LOG_LEVEL to debug|info|warn|error to override.The source: field will be one of plugin config logLevel, env SENPI_LOG_LEVEL, or default. You can confirm the active level at any time with openclaw senpi status, which prints a Log Level: <level> line for each running runtime (also available under openclaw senpi state).
What each level shows
warn/error— failures, retries, clearinghouse unavailable, scanner watchdog alerts.info(default) — the above, plus lifecycle events (open/close positions, scanner signal processed), DSL monitor ticks when there are active positions, position-tracker scans when positions or deltas change.debug— the above, plus per-tick scanner heartbeats, DSL monitor ticks with zero active positions, and full MCP tool-call request/response envelopes (with secrets redacted). Useful for diagnosing individual scan or price-fetch behavior; very noisy.
Notifications
- Strategy-level: Set
notifications.telegram_chat_idin your strategy YAML to receive alerts (e.g. open/close, decision errors, scanner watchdog). The plugin sends messages via the OpenClaw gatewaymessagetool (action: send,target: telegram:<chatId>). - Lifecycle (plugin start/stop): Set
SENPI_LIFECYCLE_TELEGRAM_CHAT_IDin the gateway environment (e.g. in Docker: add todocker-composeand.env) to receive "Senpi started. Strategy running." when the plugin service starts and "Senpi shutting down." when it stops. RequiresOPENCLAW_GATEWAY_TOKEN(and optionallyOPENCLAW_GATEWAY_URL) in the same environment.
Auto-update
Auto-update is enabled by default (opt-out). When a new minor or patch version is published to npm, the plugin will install it automatically and attempt to restart the OpenClaw gateway so the new code takes effect.
- Major versions are never auto-installed. A Telegram notification is sent instead, asking you to review the changelog and update manually.
- Default mode:
auto-apply— the plugin polls every 6 hours, installs the update, and triggers a gateway restart. - Gateway restart requires
gateway.reload.modeset torestartorhybridin your OpenClaw config. If the mode ishotoroff, or the config helpers are unavailable, the plugin will send a notification asking you to restart the gateway manually.
To customise or disable auto-update, add an autoUpdate block to the plugin config:
{
"plugins": {
"entries": {
"runtime": {
"enabled": true,
"config": {
"autoUpdate": {
"mode": "notify-only",
"pollIntervalMinutes": 720
}
}
}
}
}
}Set "enabled": false inside the autoUpdate block to disable it entirely.
Known limitation: If the gateway cannot be restarted automatically (wrong reload mode or missing config access), runtimes that were stopped for the update remain stopped until you restart the gateway manually.
Risk guardrails
Strategy YAML may include a risk block with guard_rails (daily loss, drawdown, max entries per day, consecutive-loss cooldown, per-asset cooldown, and optional bypass when the day is profitable at the entry cap). Gates are evaluated in real time via MCP before each open. See docs/risk-component.md for gate order, data sources, and semantics.
Quickstart
Copy a minimal recipe template and set your wallet:
cp $(openclaw plugins path @senpi-ai/runtime)/examples/strategies/minimal.yaml ~/my-recipe.yaml # Edit my-recipe.yaml: replace ${WALLET_ADDRESS} or set WALLET_ADDRESS in envSet environment variables (e.g.
.env):SENPI_API_KEY,WALLET_ADDRESS.Load the recipe (hot-loads; no gateway restart):
openclaw senpi runtime create -p ~/my-recipe.yamlList recipes:
openclaw senpi runtime listWatch gateway logs for scanner runs and signal processing.
Strategy templates
| File | Style | Scanners | Use case | |------|-------|----------|----------| | minimal.yaml | Watch-only | emerging_movers | Verify setup; no positions | | wolf.yaml | Aggressive | emerging_movers | Early entry on FIRST_JUMP | | viper.yaml | Moderate | prescreener + momentum | Candle-based breakouts | | fox.yaml | OI-driven | prescreener + oi_tracker | OI-driven entries | | dsl-showcase.yaml | DSL reference | emerging_movers | Annotated exit config |
Templates live under examples/strategies/ in the package. See examples/strategies/README.md.
CLI reference
Runtime recipes:
openclaw senpi runtime create -p <path>— create from YAML file (hot-load)openclaw senpi runtime create -c "<yaml>"— create from inline YAMLopenclaw senpi runtime list— list installed runtimesopenclaw senpi runtime delete <runtime_id>— remove by id
In-shell reference:
openclaw senpi guide— overviewopenclaw senpi guide scanners— scanner types and config fieldsopenclaw senpi guide actions— action types and decision modesopenclaw senpi guide dsl— DSL two-phase exit engineopenclaw senpi guide examples— print minimal strategy YAMLopenclaw senpi guide schema— full YAML schemaopenclaw senpi guide version— plugin version and changelog URL
HTTP API
The runtime exposes an HTTP API on 127.0.0.1:8787 (default; configurable via plugin config). Use it to ingest signals from external sources, query audit history, and check liveness.
Three endpoints:
POST /signals— ingest external scanner signals; body is a JSON array of signal itemsGET /audit?address=<wallet>— query strategy audit history via MCPGET /health— liveness probe with per-runtime signal queue depth
Default binding: 127.0.0.1:8787 (localhost-only). For Postman testing on the same host, flip api.host to 0.0.0.0 in openclaw.json and add a Docker port mapping 127.0.0.1:8787:8787 (the 127.0.0.1: prefix is mandatory to avoid LAN exposure). See docs/runtime-docs/runtime-api.md for full details and the Postman testing recipe.
Latency benchmark: npm run bench runs benchmarks/ingest-latency.ts — compares the in-process gateway-shim path against HTTP POST /signals across three scenarios and prints p50/p95/p99 with a PASS/FAIL gate.
External scanners
Use type: external_scanner when the signal or context source lives outside the
runtime and should push data in through the gateway instead of being scheduled
on an interval.
scanners:
- name: funding_arb
type: external_scanner
outputs:
signals: true
context: false
retention: rolling_window
retention_max_runs: 50
config:
fields:
funding_rate: { type: number, required: true }
spread: { type: number, required: true }
exchange: { type: string }Ingest data with the gateway RPC:
openclaw gateway call senpi.ingestExternalScannerData --params '{
"address": "0xYourStrategyWallet",
"scanner": "funding_arb",
"asset": "ETH-PERP",
"direction": "LONG",
"score": 0.91,
"signal_type": "EXTERNAL_FUNDING_ARB",
"data": {
"funding_rate": 0.015,
"spread": 0.003,
"exchange": "binance"
}
}'Prompt access stays namespaced:
{{signal_funding_arb}}for ingested signals{{context_custom_regime}}for retained external context- flat aliases like
{{funding_arb}}are not created
Guide skill
Once published, the @senpi-guide skill on ClawHub provides the same reference in chat. Install with clawhub install skills/senpi-guide/ (or from the ClawHub UI).
Install on an existing OpenClaw setup
If you already have OpenClaw installed (local, VPS, or self-hosted), see Installing on existing OpenClaw for the full install sequence, config stanza, and troubleshooting.
Docs
Changelog
Development
npm run build # install deps + compile TypeScript (excludes *.test.ts)
npm run typecheck:tests # typecheck all src including tests (no emit)
npm test # unit + integration tests (no credentials required)
npm run dev # build + runPre-commit runs npm run build, npm run typecheck:tests, and npm test. See CLAUDE.md and docs/runtime-docs/ for conventions and design.
