ocsmarttools 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +169 -0
- package/openclaw.plugin.json +48 -0
- package/package.json +33 -0
- package/src/commands/chat.ts +123 -0
- package/src/commands/cli.ts +130 -0
- package/src/commands/operations.ts +370 -0
- package/src/index.ts +70 -0
- package/src/lib/bootstrap.ts +114 -0
- package/src/lib/invoke.ts +202 -0
- package/src/lib/metrics-store.ts +177 -0
- package/src/lib/plugin-config.ts +143 -0
- package/src/lib/refs.ts +68 -0
- package/src/lib/result-shaper.ts +237 -0
- package/src/lib/result-store.ts +72 -0
- package/src/lib/tool-catalog.ts +339 -0
- package/src/tools/tool-batch.ts +374 -0
- package/src/tools/tool-dispatch.ts +157 -0
- package/src/tools/tool-result-get.ts +65 -0
- package/src/tools/tool-search.ts +72 -0
- package/src/types/openclaw-plugin-sdk.d.ts +78 -0
- package/tsconfig.json +14 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `ocsmarttools` are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.1.2] - 2026-02-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Lightweight metrics tracking for tool invocations: success/failure/timeout, latency, shaped-result rate, and approximate token savings.
|
|
9
|
+
- Chat and CLI stats commands (`/ocsmarttools stats`, `/ocsmarttools stats reset`, `openclaw ocsmarttools stats`, `openclaw ocsmarttools stats reset`).
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `tool_search` now tries live gateway registry endpoints first and falls back to policy/static catalog automatically.
|
|
13
|
+
- Added `toolSearch.useLiveRegistry` and `toolSearch.liveTimeoutMs` config options.
|
|
14
|
+
|
|
15
|
+
## [0.1.1] - 2026-02-22
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- `version` commands in chat and CLI (`/ocsmarttools version`, `openclaw ocsmarttools version`).
|
|
19
|
+
- Version control scripts in `package.json` (`version:show`, `version:bump:*`, `release:check`).
|
|
20
|
+
- `CHANGELOG.md` for release notes tracking.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- `setup` default mode now aligns with zero-touch defaults (`standard`).
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Blocked `tool_dispatch` from dispatching internal orchestration tools (`tool_dispatch`, `tool_batch`) to avoid nested orchestration loops.
|
|
27
|
+
|
|
28
|
+
## [0.1.0] - 2026-02-22
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Provider-agnostic tool orchestration tools: `tool_search`, `tool_dispatch`, `tool_batch`, `tool_result_get`.
|
|
32
|
+
- Zero-touch auto-bootstrap on plugin start.
|
|
33
|
+
- Chat and CLI setup/status/mode/config commands.
|
|
34
|
+
- Help commands in chat and CLI.
|
|
35
|
+
- Adaptive large-result shaping with handle-based retrieval.
|
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# OCSmartTools for OpenClaw
|
|
2
|
+
|
|
3
|
+
Provider-agnostic tool orchestration for lower latency and lower token cost.
|
|
4
|
+
|
|
5
|
+
`ocsmarttools` is designed to work immediately after install, with safe defaults and minimal setup.
|
|
6
|
+
|
|
7
|
+
## What It Adds
|
|
8
|
+
|
|
9
|
+
- `tool_search`: finds relevant tools quickly
|
|
10
|
+
- `tool_dispatch`: runs one tool call through normal OpenClaw policy checks
|
|
11
|
+
- `tool_batch`: runs bounded multi-step workflows (`call` + `foreach`)
|
|
12
|
+
- `tool_result_get`: retrieves large stored outputs by handle
|
|
13
|
+
|
|
14
|
+
## Why It Helps
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart LR
|
|
18
|
+
A["Traditional"] --> B["Model -> tool -> model -> tool"] --> C["More turns + repeated context"]
|
|
19
|
+
D["ocsmarttools"] --> E["Batch + shaped results"] --> F["Fewer turns + smaller context"]
|
|
20
|
+
C --> G["Higher cost/latency"]
|
|
21
|
+
F --> H["Lower cost/latency"]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
### npm
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
openclaw plugins install ocsmarttools --pin
|
|
30
|
+
openclaw plugins enable ocsmarttools
|
|
31
|
+
openclaw gateway restart
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Local folder
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
openclaw plugins install /absolute/path/to/OpenClaw-SmartToolCalls
|
|
38
|
+
openclaw plugins enable ocsmarttools
|
|
39
|
+
openclaw gateway restart
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
1. Install + enable + restart.
|
|
45
|
+
2. Done. The plugin auto-bootstraps and starts working in background.
|
|
46
|
+
3. Optional check:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
/ocsmarttools status
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Model note:
|
|
53
|
+
- No model setup is required in this plugin.
|
|
54
|
+
- It automatically uses the model OpenClaw is already using.
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
### Chat Commands
|
|
59
|
+
|
|
60
|
+
| Command | What it does |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `/ocsmarttools version` | Shows installed plugin version |
|
|
63
|
+
| `/ocsmarttools help` | Shows simple help and examples |
|
|
64
|
+
| `/ocsmarttools status` | Shows current mode, limits, and safety flags |
|
|
65
|
+
| `/ocsmarttools stats` | Shows live usage metrics (success/failure/timeout, latency, shaping, savings) |
|
|
66
|
+
| `/ocsmarttools stats reset` | Resets the stats window |
|
|
67
|
+
| `/ocsmarttools setup [safe\|standard]` | Applies recommended defaults for the selected mode |
|
|
68
|
+
| `/ocsmarttools mode <safe\|standard>` | Changes mode only |
|
|
69
|
+
| `/ocsmarttools config` | Shows effective plugin config |
|
|
70
|
+
| `/ocsmarttools config keys` | Lists editable config keys |
|
|
71
|
+
| `/ocsmarttools config set <key> <value>` | Updates one config key with validation |
|
|
72
|
+
| `/ocsmarttools config reset [key]` | Resets one key (or all keys) to defaults |
|
|
73
|
+
|
|
74
|
+
### CLI Commands
|
|
75
|
+
|
|
76
|
+
| Command | What it does |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `openclaw ocsmarttools version` | Shows installed plugin version |
|
|
79
|
+
| `openclaw ocsmarttools help` | Shows simple help and examples |
|
|
80
|
+
| `openclaw ocsmarttools status` | Shows current mode, limits, and safety flags |
|
|
81
|
+
| `openclaw ocsmarttools stats` | Shows live usage metrics (success/failure/timeout, latency, shaping, savings) |
|
|
82
|
+
| `openclaw ocsmarttools stats reset` | Resets the stats window |
|
|
83
|
+
| `openclaw ocsmarttools setup [safe\|standard]` | Applies recommended defaults for the selected mode |
|
|
84
|
+
| `openclaw ocsmarttools mode <safe\|standard>` | Changes mode only |
|
|
85
|
+
| `openclaw ocsmarttools config` | Shows effective plugin config |
|
|
86
|
+
| `openclaw ocsmarttools config keys` | Lists editable config keys |
|
|
87
|
+
| `openclaw ocsmarttools config set <key> <value>` | Updates one config key with validation |
|
|
88
|
+
| `openclaw ocsmarttools config reset [key]` | Resets one key (or all keys) to defaults |
|
|
89
|
+
|
|
90
|
+
## Common Config Actions
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
/ocsmarttools config
|
|
94
|
+
/ocsmarttools config keys
|
|
95
|
+
/ocsmarttools config set maxResultChars 120000
|
|
96
|
+
/ocsmarttools config set storeLargeResults true
|
|
97
|
+
/ocsmarttools config set toolSearch.useLiveRegistry true
|
|
98
|
+
/ocsmarttools config set toolSearch.liveTimeoutMs 1500
|
|
99
|
+
/ocsmarttools config reset maxResultChars
|
|
100
|
+
/ocsmarttools stats
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Config path:
|
|
104
|
+
- `plugins.entries.ocsmarttools.config`
|
|
105
|
+
|
|
106
|
+
## Modes
|
|
107
|
+
|
|
108
|
+
- `standard` (default): zero-touch mode, no sandbox requirement, control-plane dispatch still blocked
|
|
109
|
+
- `safe`: requires sandboxed execution and blocks control-plane dispatch (`gateway`, `cron`)
|
|
110
|
+
|
|
111
|
+
Setup default:
|
|
112
|
+
- `/ocsmarttools setup` and `openclaw ocsmarttools setup` default to `standard`.
|
|
113
|
+
|
|
114
|
+
## Recommended Defaults
|
|
115
|
+
|
|
116
|
+
For mixed daily usage (research + writing + coding):
|
|
117
|
+
|
|
118
|
+
- `maxResultChars`: `120000`
|
|
119
|
+
- `storeLargeResults`: `true`
|
|
120
|
+
- `resultStoreTtlSec`: `3600`
|
|
121
|
+
- `resultSampleItems`: `10`
|
|
122
|
+
|
|
123
|
+
Example:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
/ocsmarttools config set maxResultChars 120000
|
|
127
|
+
/ocsmarttools config set resultStoreTtlSec 3600
|
|
128
|
+
/ocsmarttools config set resultSampleItems 10
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Strict Policy Note
|
|
132
|
+
|
|
133
|
+
If your instance uses strict `tools.allow`, include:
|
|
134
|
+
|
|
135
|
+
```json5
|
|
136
|
+
{
|
|
137
|
+
tools: {
|
|
138
|
+
allow: ["tool_search", "tool_dispatch", "tool_batch", "tool_result_get"]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Safety and Limits
|
|
144
|
+
|
|
145
|
+
- `ocsmarttools` does not bypass OpenClaw tool policy.
|
|
146
|
+
- `tool_batch` is intentionally bounded (`maxSteps`, `maxForEach`).
|
|
147
|
+
- Large-result handles are in-memory and expire by TTL.
|
|
148
|
+
- `tool_result_get` works only while handle is still valid.
|
|
149
|
+
- `tool_search` tries live registry endpoints first, then automatically falls back to policy/static catalog.
|
|
150
|
+
|
|
151
|
+
## Development
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm install
|
|
155
|
+
npm run typecheck
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Versioning
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm run version:show
|
|
162
|
+
npm run version:bump:patch
|
|
163
|
+
npm run version:bump:minor
|
|
164
|
+
npm run version:bump:major
|
|
165
|
+
npm run release:check
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- Version source of truth: `package.json`.
|
|
169
|
+
- Release notes: `CHANGELOG.md`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ocsmarttools",
|
|
3
|
+
"name": "OCSmartTools",
|
|
4
|
+
"description": "Provider-agnostic advanced tool orchestration with adaptive large-result handling and zero-touch startup.",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"enabled": { "type": "boolean" },
|
|
10
|
+
"mode": { "type": "string", "enum": ["safe", "standard"] },
|
|
11
|
+
"maxSteps": { "type": "integer", "minimum": 1, "maximum": 200 },
|
|
12
|
+
"maxForEach": { "type": "integer", "minimum": 1, "maximum": 200 },
|
|
13
|
+
"maxResultChars": { "type": "integer", "minimum": 500, "maximum": 500000 },
|
|
14
|
+
"invokeTimeoutMs": { "type": "integer", "minimum": 0, "maximum": 1800000 },
|
|
15
|
+
"storeLargeResults": { "type": "boolean" },
|
|
16
|
+
"resultStoreTtlSec": { "type": "integer", "minimum": 60, "maximum": 86400 },
|
|
17
|
+
"resultSampleItems": { "type": "integer", "minimum": 1, "maximum": 50 },
|
|
18
|
+
"requireSandbox": { "type": "boolean" },
|
|
19
|
+
"denyControlPlane": { "type": "boolean" },
|
|
20
|
+
"toolSearch": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"properties": {
|
|
24
|
+
"enabled": { "type": "boolean" },
|
|
25
|
+
"defaultLimit": { "type": "integer", "minimum": 1, "maximum": 50 },
|
|
26
|
+
"useLiveRegistry": { "type": "boolean" },
|
|
27
|
+
"liveTimeoutMs": { "type": "integer", "minimum": 250, "maximum": 10000 }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"uiHints": {
|
|
33
|
+
"mode": { "label": "Mode" },
|
|
34
|
+
"maxSteps": { "label": "Max Steps", "advanced": true },
|
|
35
|
+
"maxForEach": { "label": "Max ForEach", "advanced": true },
|
|
36
|
+
"maxResultChars": { "label": "Max Result Chars", "advanced": true },
|
|
37
|
+
"invokeTimeoutMs": { "label": "Invoke Timeout (ms)", "advanced": true },
|
|
38
|
+
"storeLargeResults": { "label": "Store Large Results", "advanced": true },
|
|
39
|
+
"resultStoreTtlSec": { "label": "Result Store TTL (sec)", "advanced": true },
|
|
40
|
+
"resultSampleItems": { "label": "Result Sample Items", "advanced": true },
|
|
41
|
+
"requireSandbox": { "label": "Require Sandbox", "advanced": true },
|
|
42
|
+
"denyControlPlane": { "label": "Deny Control Plane", "advanced": true },
|
|
43
|
+
"toolSearch.enabled": { "label": "Enable Tool Search" },
|
|
44
|
+
"toolSearch.defaultLimit": { "label": "Tool Search Default Limit", "advanced": true },
|
|
45
|
+
"toolSearch.useLiveRegistry": { "label": "Use Live Tool Registry", "advanced": true },
|
|
46
|
+
"toolSearch.liveTimeoutMs": { "label": "Live Tool Registry Timeout (ms)", "advanced": true }
|
|
47
|
+
}
|
|
48
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ocsmarttools",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Provider-agnostic advanced tool orchestration plugin for OpenClaw with search, dispatch, and batching",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"typecheck": "tsc --noEmit",
|
|
8
|
+
"release:check": "npm run typecheck && npm pack --dry-run",
|
|
9
|
+
"version:show": "node -p \"require('./package.json').version\"",
|
|
10
|
+
"version:bump:patch": "npm version patch --no-git-tag-version",
|
|
11
|
+
"version:bump:minor": "npm version minor --no-git-tag-version",
|
|
12
|
+
"version:bump:major": "npm version major --no-git-tag-version"
|
|
13
|
+
},
|
|
14
|
+
"openclaw": {
|
|
15
|
+
"extensions": [
|
|
16
|
+
"./src/index.ts"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"openclaw",
|
|
21
|
+
"plugin",
|
|
22
|
+
"tools",
|
|
23
|
+
"agent"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"openclaw": ">=2026.2.21"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.8.0",
|
|
31
|
+
"@types/node": "^22.10.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import {
|
|
3
|
+
applySetup,
|
|
4
|
+
canEditConfigKey,
|
|
5
|
+
normalizeConfigKey,
|
|
6
|
+
renderConfig,
|
|
7
|
+
renderConfigKeys,
|
|
8
|
+
renderHelp,
|
|
9
|
+
renderStatus,
|
|
10
|
+
renderStats,
|
|
11
|
+
renderVersion,
|
|
12
|
+
resetStats,
|
|
13
|
+
resetConfig,
|
|
14
|
+
setConfigKey,
|
|
15
|
+
updateMode,
|
|
16
|
+
} from "./operations.js";
|
|
17
|
+
import type { AdvToolsMode } from "../lib/plugin-config.js";
|
|
18
|
+
import type { MetricsStore } from "../lib/metrics-store.js";
|
|
19
|
+
|
|
20
|
+
function parseMode(value: string | undefined): AdvToolsMode | null {
|
|
21
|
+
if (value === "safe" || value === "standard") {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function registerChatCommands(api: OpenClawPluginApi, metrics: MetricsStore): void {
|
|
28
|
+
api.registerCommand({
|
|
29
|
+
name: "ocsmarttools",
|
|
30
|
+
description: "OCSmartTools setup/status helper.",
|
|
31
|
+
acceptsArgs: true,
|
|
32
|
+
handler: async (ctx) => {
|
|
33
|
+
const args = (ctx.args ?? "").trim();
|
|
34
|
+
if (!args) {
|
|
35
|
+
return { text: renderHelp() };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parts = args.split(/\s+/);
|
|
39
|
+
const cmd = parts[0]?.toLowerCase();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (cmd === "status") {
|
|
43
|
+
return { text: renderStatus(api) };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (cmd === "version") {
|
|
47
|
+
return { text: renderVersion(api) };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (cmd === "help") {
|
|
51
|
+
return { text: renderHelp() };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (cmd === "stats") {
|
|
55
|
+
const action = (parts[1] ?? "").toLowerCase();
|
|
56
|
+
if (action === "reset") {
|
|
57
|
+
return { text: resetStats(metrics) };
|
|
58
|
+
}
|
|
59
|
+
return { text: renderStats(metrics) };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (cmd === "setup") {
|
|
63
|
+
const mode = parseMode(parts[1]) ?? "standard";
|
|
64
|
+
return { text: await applySetup(api, mode) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (cmd === "mode") {
|
|
68
|
+
const mode = parseMode(parts[1]);
|
|
69
|
+
if (!mode) {
|
|
70
|
+
return { text: "Usage: /ocsmarttools mode <safe|standard>" };
|
|
71
|
+
}
|
|
72
|
+
return { text: await updateMode(api, mode) };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (cmd === "config") {
|
|
76
|
+
const action = (parts[1] ?? "get").toLowerCase();
|
|
77
|
+
if (action === "get") {
|
|
78
|
+
return { text: renderConfig(api) };
|
|
79
|
+
}
|
|
80
|
+
if (action === "keys") {
|
|
81
|
+
return { text: renderConfigKeys() };
|
|
82
|
+
}
|
|
83
|
+
if (action === "set") {
|
|
84
|
+
const key = normalizeConfigKey(parts[2] ?? "");
|
|
85
|
+
const valueRaw = parts.slice(3).join(" ").trim();
|
|
86
|
+
if (!key || !valueRaw) {
|
|
87
|
+
return { text: "Usage: /ocsmarttools config set <key> <value>" };
|
|
88
|
+
}
|
|
89
|
+
if (!canEditConfigKey(key)) {
|
|
90
|
+
return { text: `Unknown key: ${key}. Use \`/ocsmarttools config keys\`.` };
|
|
91
|
+
}
|
|
92
|
+
return { text: await setConfigKey(api, key, valueRaw) };
|
|
93
|
+
}
|
|
94
|
+
if (action === "reset") {
|
|
95
|
+
const key = normalizeConfigKey(parts[2] ?? "");
|
|
96
|
+
if (key && !canEditConfigKey(key)) {
|
|
97
|
+
return { text: `Unknown key: ${key}. Use \`/ocsmarttools config keys\`.` };
|
|
98
|
+
}
|
|
99
|
+
return { text: await resetConfig(api, key || undefined) };
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
text: [
|
|
103
|
+
"Usage:",
|
|
104
|
+
"/ocsmarttools config",
|
|
105
|
+
"/ocsmarttools config get",
|
|
106
|
+
"/ocsmarttools config keys",
|
|
107
|
+
"/ocsmarttools config set <key> <value>",
|
|
108
|
+
"/ocsmarttools config reset [key]",
|
|
109
|
+
].join("\n"),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
text: "Unknown subcommand. Use `/ocsmarttools help`.",
|
|
115
|
+
};
|
|
116
|
+
} catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
text: `ocsmarttools error: ${error instanceof Error ? error.message : String(error)}`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import {
|
|
3
|
+
applySetup,
|
|
4
|
+
renderConfig,
|
|
5
|
+
renderConfigKeys,
|
|
6
|
+
renderHelp,
|
|
7
|
+
renderStatus,
|
|
8
|
+
renderStats,
|
|
9
|
+
renderVersion,
|
|
10
|
+
resetStats,
|
|
11
|
+
resetConfig,
|
|
12
|
+
setConfigKey,
|
|
13
|
+
updateMode,
|
|
14
|
+
} from "./operations.js";
|
|
15
|
+
import type { AdvToolsMode } from "../lib/plugin-config.js";
|
|
16
|
+
import type { MetricsStore } from "../lib/metrics-store.js";
|
|
17
|
+
|
|
18
|
+
function parseMode(value: string | undefined): AdvToolsMode | null {
|
|
19
|
+
if (value === "safe" || value === "standard") {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function registerCliCommands(api: OpenClawPluginApi, metrics: MetricsStore): void {
|
|
26
|
+
api.registerCli(
|
|
27
|
+
({ program }) => {
|
|
28
|
+
const adv = program.command("ocsmarttools").description("OCSmartTools plugin commands");
|
|
29
|
+
adv.addHelpCommand(false);
|
|
30
|
+
|
|
31
|
+
adv
|
|
32
|
+
.command("help")
|
|
33
|
+
.description("Show simple command guide")
|
|
34
|
+
.action(() => {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.log(renderHelp());
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
adv
|
|
40
|
+
.command("version")
|
|
41
|
+
.description("Show installed plugin version")
|
|
42
|
+
.action(() => {
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.log(renderVersion(api));
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
adv
|
|
48
|
+
.command("status")
|
|
49
|
+
.description("Show plugin status")
|
|
50
|
+
.action(() => {
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.log(renderStatus(api));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
adv
|
|
56
|
+
.command("stats")
|
|
57
|
+
.description("Show usage/savings metrics")
|
|
58
|
+
.action(() => {
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.log(renderStats(metrics));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
adv
|
|
64
|
+
.command("stats reset")
|
|
65
|
+
.description("Reset usage/savings metrics window")
|
|
66
|
+
.action(() => {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.log(resetStats(metrics));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
adv
|
|
72
|
+
.command("setup [mode]")
|
|
73
|
+
.description("Apply recommended setup (default mode: standard)")
|
|
74
|
+
.action(async (modeRaw?: string) => {
|
|
75
|
+
const mode = parseMode(modeRaw) ?? "standard";
|
|
76
|
+
const text = await applySetup(api, mode);
|
|
77
|
+
// eslint-disable-next-line no-console
|
|
78
|
+
console.log(text);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
adv
|
|
82
|
+
.command("mode <mode>")
|
|
83
|
+
.description("Set plugin mode")
|
|
84
|
+
.action(async (modeRaw: string) => {
|
|
85
|
+
const mode = parseMode(modeRaw);
|
|
86
|
+
if (!mode) {
|
|
87
|
+
throw new Error("mode must be one of: safe, standard");
|
|
88
|
+
}
|
|
89
|
+
const text = await updateMode(api, mode);
|
|
90
|
+
// eslint-disable-next-line no-console
|
|
91
|
+
console.log(text);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
adv
|
|
95
|
+
.command("config")
|
|
96
|
+
.description("Show effective plugin config")
|
|
97
|
+
.action(() => {
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.log(renderConfig(api));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
adv
|
|
103
|
+
.command("config keys")
|
|
104
|
+
.description("List editable plugin config keys")
|
|
105
|
+
.action(() => {
|
|
106
|
+
// eslint-disable-next-line no-console
|
|
107
|
+
console.log(renderConfigKeys());
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
adv
|
|
111
|
+
.command("config set <key> <value>")
|
|
112
|
+
.description("Set one plugin config key")
|
|
113
|
+
.action(async (key: string, value: string) => {
|
|
114
|
+
const text = await setConfigKey(api, key, value);
|
|
115
|
+
// eslint-disable-next-line no-console
|
|
116
|
+
console.log(text);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
adv
|
|
120
|
+
.command("config reset [key]")
|
|
121
|
+
.description("Reset all plugin config to defaults or reset one key")
|
|
122
|
+
.action(async (key?: string) => {
|
|
123
|
+
const text = await resetConfig(api, key);
|
|
124
|
+
// eslint-disable-next-line no-console
|
|
125
|
+
console.log(text);
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
{ commands: ["ocsmarttools"] },
|
|
129
|
+
);
|
|
130
|
+
}
|