Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions openclaw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# RTK Plugin for OpenClaw

Transparently rewrites shell commands executed via OpenClaw's `exec` tool to their RTK equivalents, achieving 60-90% LLM token savings.

This is the OpenClaw equivalent of the Claude Code hooks in `hooks/rtk-rewrite.sh`.

## How it works

The plugin registers a `before_tool_call` hook that intercepts `exec` tool calls. When the agent runs a command like `git status`, the plugin delegates to `rtk rewrite` which returns the optimized command (e.g. `rtk git status`). The compressed output enters the agent's context window, saving tokens.

All rewrite logic lives in RTK itself (`rtk rewrite`). This plugin is a thin delegate -- when new filters are added to RTK, the plugin picks them up automatically with zero changes.

## Installation

### Prerequisites

RTK must be installed and available in `$PATH`:

```bash
brew install rtk
# or
curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh
```

### Install the plugin

```bash
# Copy the plugin to OpenClaw's extensions directory
mkdir -p ~/.openclaw/extensions/rtk-rewrite
cp openclaw/index.ts openclaw/openclaw.plugin.json ~/.openclaw/extensions/rtk-rewrite/

# Restart the gateway
openclaw gateway restart
```

### Or install via OpenClaw CLI

```bash
openclaw plugins install ./openclaw
```

## Configuration

In `openclaw.json`:

```json5
{
plugins: {
entries: {
"rtk-rewrite": {
enabled: true,
config: {
enabled: true, // Toggle rewriting on/off
verbose: false // Log rewrites to console
}
}
}
}
}
```

## What gets rewritten

Everything that `rtk rewrite` supports (30+ commands). See the [full command list](https://github.com/rtk-ai/rtk#commands).

## What's NOT rewritten

Handled by `rtk rewrite` guards:
- Commands already using `rtk`
- Piped commands (`|`, `&&`, `;`)
- Heredocs (`<<`)
- Commands without an RTK filter

## Measured savings

| Command | Token savings |
|---------|--------------|
| `git log --stat` | 87% |
| `ls -la` | 78% |
| `git status` | 66% |
| `grep` (single file) | 52% |
| `find -name` | 48% |

## License

MIT -- same as RTK.
74 changes: 74 additions & 0 deletions openclaw/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* RTK Rewrite Plugin for OpenClaw
*
* Transparently rewrites exec tool commands to RTK equivalents
* before execution, achieving 60-90% LLM token savings.
*
* All rewrite logic lives in `rtk rewrite` (src/discover/registry.rs).
* This plugin is a thin delegate — to add or change rules, edit the
* Rust registry, not this file.
*/

import { execSync } from "node:child_process";

let rtkAvailable: boolean | null = null;

function checkRtk(): boolean {
if (rtkAvailable !== null) return rtkAvailable;
try {
execSync("which rtk", { stdio: "ignore" });
rtkAvailable = true;
} catch {
rtkAvailable = false;
}
return rtkAvailable;
}

function tryRewrite(command: string): string | null {
try {
const result = execSync(`rtk rewrite ${JSON.stringify(command)}`, {
encoding: "utf-8",
timeout: 2000,
}).trim();
return result && result !== command ? result : null;
} catch {
return null;
}
}

export default function register(api: any) {
const pluginConfig = api.config ?? {};
const enabled = pluginConfig.enabled !== false;
const verbose = pluginConfig.verbose === true;

if (!enabled) return;

if (!checkRtk()) {
console.warn("[rtk] rtk binary not found in PATH — plugin disabled");
return;
}

api.on(
"before_tool_call",
(event: { toolName: string; params: Record<string, unknown> }) => {
if (event.toolName !== "exec") return;

const command = event.params?.command;
if (typeof command !== "string") return;

const rewritten = tryRewrite(command);
if (!rewritten) return;

if (verbose) {
console.log(`[rtk] ${command} -> ${rewritten}`);
}

return { params: { ...event.params, command: rewritten } };
},
{ priority: 10 }
);

if (verbose) {
console.log("[rtk] OpenClaw plugin registered");
}
}
28 changes: 28 additions & 0 deletions openclaw/openclaw.plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"id": "rtk-rewrite",
"name": "RTK Token Optimizer",
"version": "1.0.0",
"description": "Transparently rewrites shell commands to their RTK equivalents for 60-90% LLM token savings",
"homepage": "https://github.com/rtk-ai/rtk",
"license": "MIT",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Enable automatic command rewriting to RTK equivalents"
},
"verbose": {
"type": "boolean",
"default": false,
"description": "Log rewrite decisions to console for debugging"
}
}
},
"uiHints": {
"enabled": { "label": "Enable RTK rewriting" },
"verbose": { "label": "Verbose logging" }
}
}
29 changes: 29 additions & 0 deletions openclaw/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@rtk-ai/rtk-rewrite",
"version": "1.0.0",
"description": "RTK plugin for OpenClaw — rewrites shell commands for 60-90% LLM token savings",
"main": "index.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/rtk-ai/rtk",
"directory": "openclaw"
},
"homepage": "https://github.com/rtk-ai/rtk",
"keywords": [
"rtk",
"openclaw",
"openclaw-plugin",
"token-savings",
"llm",
"cli-proxy"
],
"files": [
"index.ts",
"openclaw.plugin.json",
"README.md"
],
"peerDependencies": {
"rtk": ">=0.28.0"
}
}
Loading