ocsmarttools 0.1.9 → 0.1.10

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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to `ocsmarttools` are documented here.
4
4
 
5
+ ## [0.1.10] - 2026-02-22
6
+
7
+ ### Changed
8
+ - Expanded auto-routing trigger intents in managed `AGENTS.md` policy to cover:
9
+ - research/evidence
10
+ - reporting/writing
11
+ - coding/engineering
12
+ - data/extraction
13
+ - risk/compliance
14
+ - Expanded built-in `tool_search` keyword coverage across runtime, filesystem, web, browser, and session tools for broader intent matching.
15
+ - Improved `tool_search` scoring tokenization so punctuation-heavy terms (for example `CI/CD`) match more reliably.
16
+
5
17
  ## [0.1.9] - 2026-02-22
6
18
 
7
19
  ### Changed
package/README.md CHANGED
@@ -15,7 +15,7 @@ OCSmartTools helps reduce latency and token cost by routing multi-step work thro
15
15
  - `tool_result_get`
16
16
  - Built-in metrics for success/failure/timeout, latency, and estimated savings
17
17
  - Skill-compatible (including browser/Playwright-style workflows)
18
- - Auto-managed routing guidance for research/report tasks (no per-prompt guardrails needed)
18
+ - Auto-managed routing guidance for research/report/coding/data tasks (no per-prompt guardrails needed)
19
19
 
20
20
  ## Install
21
21
 
@@ -96,6 +96,15 @@ Example:
96
96
  - `safe`: requires sandbox and blocks control-plane dispatch
97
97
  - `strictRouting=true`: enforces plugin-managed routing guidance and keeps routing block synced
98
98
 
99
+ ## Auto Trigger Intents
100
+
101
+ When tools are needed, routing is auto-biased toward `tool_dispatch` / `tool_batch` for these intent families:
102
+ - research/evidence (sources, benchmarks, case studies, latest/news)
103
+ - reporting/writing (reports, briefs, proposals, plans, emails, docs/specs)
104
+ - coding/engineering (build, debug, fix, test, refactor, deploy, migration)
105
+ - data/extraction (scrape/fetch/parse/aggregate/rank/CSV/JSON/ETL)
106
+ - risk/compliance (security/privacy/legal/audit requests)
107
+
99
108
  ## Skills and Blocked Sites
100
109
 
101
110
  Skills in OpenClaw are instruction layers, not separate execution engines. OCSmartTools can still dispatch/batch the underlying tools used by skills.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocsmarttools",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Provider-agnostic advanced tool orchestration plugin for OpenClaw with search, dispatch, and batching",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -6,6 +6,15 @@ import type { OpenClawConfig, OpenClawPluginApi } from "openclaw/plugin-sdk";
6
6
  const BLOCK_START = "<!-- OCSMARTTOOLS_ROUTING_START -->";
7
7
  const BLOCK_END = "<!-- OCSMARTTOOLS_ROUTING_END -->";
8
8
 
9
+ const AUTO_TRIGGER_LINES = [
10
+ "Auto-route trigger intents (use routing tools by default when tools are needed):",
11
+ "- Research and evidence: research, investigate, analyze, benchmark, compare, evaluate, market intelligence, trends, latest, news, sources, citations, references, case study, due diligence.",
12
+ "- Reporting and writing: report, summary, brief, memo, presentation, plan, proposal, recommendation, email, RFC, PRD, specification, documentation, SOP.",
13
+ "- Coding and engineering: code, implement, build, website, app, script, debug, fix, bug, stack trace, test, lint, refactor, optimize, compile, deploy, CI/CD, migration, release notes.",
14
+ "- Data and extraction: scrape, crawl, fetch, parse, transform, aggregate, rank, classify, table, CSV, JSON, dataset, ETL.",
15
+ "- Risk and compliance: risk register, security review, privacy, legal, policy, SOC 2, GDPR, HIPAA, audit.",
16
+ ];
17
+
9
18
  function buildRoutingBlock(strictRouting: boolean): string {
10
19
  const body = strictRouting
11
20
  ? [
@@ -22,8 +31,11 @@ function buildRoutingBlock(strictRouting: boolean): string {
22
31
  "6. Avoid direct native tool calls unless routing tools are unavailable due to runtime/tool-policy constraints.",
23
32
  "7. Do not present citations/sources unless they came from successful tool calls in the current run.",
24
33
  "8. If required retrieval fails, return a clear partial/failure report instead of fabricated evidence.",
34
+ "9. Treat trigger intents below as routing-required unless the request is clearly a no-tool task.",
25
35
  "",
26
36
  "Common large/noisy tools: `web_fetch`, `read` (large files), `exec`, `process`, `browser`, `nodes`.",
37
+ "",
38
+ ...AUTO_TRIGGER_LINES,
27
39
  ].join("\n")
28
40
  : [
29
41
  "## OCSmartTools Routing Policy (Auto-Managed)",
@@ -38,8 +50,11 @@ function buildRoutingBlock(strictRouting: boolean): string {
38
50
  "6. Use direct native tool calls only for simple one-shot small-output actions.",
39
51
  "7. Do not include citations/sources that were not retrieved by tools in the current run.",
40
52
  "8. If retrieval fails, explicitly report the gap.",
53
+ "9. Treat trigger intents below as strong routing signals unless the task is clearly no-tool.",
41
54
  "",
42
55
  "Common large/noisy tools: `web_fetch`, `read` (large files), `exec`, `process`, `browser`, `nodes`.",
56
+ "",
57
+ ...AUTO_TRIGGER_LINES,
43
58
  ].join("\n");
44
59
 
45
60
  return `${BLOCK_START}
@@ -9,34 +9,184 @@ export type ToolEntry = {
9
9
  source: "builtin" | "policy" | "live";
10
10
  };
11
11
 
12
+ const RESEARCH_KEYWORDS = [
13
+ "research",
14
+ "investigate",
15
+ "analyze",
16
+ "analysis",
17
+ "benchmark",
18
+ "compare",
19
+ "evaluate",
20
+ "market intelligence",
21
+ "trend",
22
+ "latest",
23
+ "news",
24
+ "evidence",
25
+ "sources",
26
+ "citations",
27
+ "references",
28
+ "case study",
29
+ "due diligence",
30
+ ];
31
+
32
+ const REPORT_KEYWORDS = [
33
+ "report",
34
+ "summary",
35
+ "brief",
36
+ "memo",
37
+ "recommendation",
38
+ "proposal",
39
+ "plan",
40
+ "writeup",
41
+ "presentation",
42
+ "email",
43
+ "documentation",
44
+ "spec",
45
+ "rfc",
46
+ "prd",
47
+ ];
48
+
49
+ const CODING_KEYWORDS = [
50
+ "code",
51
+ "implement",
52
+ "build",
53
+ "website",
54
+ "app",
55
+ "script",
56
+ "debug",
57
+ "fix",
58
+ "bug",
59
+ "stack trace",
60
+ "test",
61
+ "lint",
62
+ "refactor",
63
+ "optimize",
64
+ "compile",
65
+ "deploy",
66
+ "ci",
67
+ "cd",
68
+ "migration",
69
+ ];
70
+
71
+ const DATA_KEYWORDS = [
72
+ "extract",
73
+ "scrape",
74
+ "crawl",
75
+ "parse",
76
+ "transform",
77
+ "aggregate",
78
+ "rank",
79
+ "classify",
80
+ "csv",
81
+ "json",
82
+ "dataset",
83
+ "etl",
84
+ "table",
85
+ ];
86
+
87
+ const BROWSER_KEYWORDS = [
88
+ "playwright",
89
+ "stealth",
90
+ "anti-bot",
91
+ "captcha",
92
+ "dynamic site",
93
+ "javascript page",
94
+ "login wall",
95
+ "rendered page",
96
+ "automation",
97
+ ];
98
+
12
99
  const BUILTIN: ToolEntry[] = [
13
100
  {
14
101
  name: "exec",
15
102
  group: "runtime",
16
103
  description: "Run shell commands.",
17
104
  paramsHint: "{ command }",
18
- keywords: ["script", "python", "node", "playwright", "stealth", "scrape"],
105
+ keywords: [
106
+ "shell",
107
+ "terminal",
108
+ "command line",
109
+ "python",
110
+ "node",
111
+ "npm",
112
+ "git",
113
+ "build",
114
+ "run tests",
115
+ "start server",
116
+ ...CODING_KEYWORDS,
117
+ ...DATA_KEYWORDS,
118
+ ...BROWSER_KEYWORDS,
119
+ ],
120
+ source: "builtin",
121
+ },
122
+ {
123
+ name: "bash",
124
+ group: "runtime",
125
+ description: "Alias for exec in many contexts.",
126
+ paramsHint: "{ command }",
127
+ keywords: ["shell", "terminal", "script", ...CODING_KEYWORDS],
128
+ source: "builtin",
129
+ },
130
+ {
131
+ name: "process",
132
+ group: "runtime",
133
+ description: "Manage background command sessions.",
134
+ paramsHint: "{ action, sessionId? }",
135
+ keywords: ["long running", "background job", "watch logs", "daemon", "worker", "server process", "job status"],
136
+ source: "builtin",
137
+ },
138
+ {
139
+ name: "read",
140
+ group: "fs",
141
+ description: "Read files.",
142
+ paramsHint: "{ path }",
143
+ keywords: ["open file", "inspect file", "view logs", "read config", "read docs", "audit code", ...REPORT_KEYWORDS],
144
+ source: "builtin",
145
+ },
146
+ {
147
+ name: "write",
148
+ group: "fs",
149
+ description: "Write files.",
150
+ paramsHint: "{ path, content }",
151
+ keywords: ["create file", "save output", "generate report", "draft", "write docs", "export", ...REPORT_KEYWORDS],
152
+ source: "builtin",
153
+ },
154
+ {
155
+ name: "edit",
156
+ group: "fs",
157
+ description: "Patch file text by replacement.",
158
+ paramsHint: "{ path, oldText, newText }",
159
+ keywords: ["modify file", "update code", "refactor file", "fix snippet", ...CODING_KEYWORDS],
160
+ source: "builtin",
161
+ },
162
+ {
163
+ name: "apply_patch",
164
+ group: "fs",
165
+ description: "Apply unified-style file patch.",
166
+ paramsHint: "{ input }",
167
+ keywords: ["multi-file patch", "diff", "code patch", "batch edits", "surgical edit", ...CODING_KEYWORDS],
168
+ source: "builtin",
169
+ },
170
+ { name: "sessions_list", group: "sessions", description: "List sessions.", paramsHint: "{ ... }", keywords: ["session", "agents", "workers"], source: "builtin" },
171
+ { name: "sessions_history", group: "sessions", description: "Read session history.", paramsHint: "{ sessionKey? }", keywords: ["conversation history", "chat log", "audit trail"], source: "builtin" },
172
+ { name: "sessions_send", group: "sessions", description: "Send to another session.", paramsHint: "{ ... }", keywords: ["delegate", "handoff", "subtask"], source: "builtin" },
173
+ { name: "sessions_spawn", group: "sessions", description: "Spawn subagent session.", paramsHint: "{ prompt, ... }", keywords: ["spawn agent", "parallel agent", "subagent", "delegate"], source: "builtin" },
174
+ { name: "session_status", group: "sessions", description: "Show current session status.", paramsHint: "{}", keywords: ["status", "health", "progress"], source: "builtin" },
175
+ {
176
+ name: "memory_search",
177
+ group: "memory",
178
+ description: "Search memory snippets.",
179
+ paramsHint: "{ query }",
180
+ keywords: ["recall", "memory", "previous notes", "past decisions", "context lookup"],
19
181
  source: "builtin",
20
182
  },
21
- { name: "bash", group: "runtime", description: "Alias for exec in many contexts.", paramsHint: "{ command }", source: "builtin" },
22
- { name: "process", group: "runtime", description: "Manage background command sessions.", paramsHint: "{ action, sessionId? }", source: "builtin" },
23
- { name: "read", group: "fs", description: "Read files.", paramsHint: "{ path }", source: "builtin" },
24
- { name: "write", group: "fs", description: "Write files.", paramsHint: "{ path, content }", source: "builtin" },
25
- { name: "edit", group: "fs", description: "Patch file text by replacement.", paramsHint: "{ path, oldText, newText }", source: "builtin" },
26
- { name: "apply_patch", group: "fs", description: "Apply unified-style file patch.", paramsHint: "{ input }", source: "builtin" },
27
- { name: "sessions_list", group: "sessions", description: "List sessions.", paramsHint: "{ ... }", source: "builtin" },
28
- { name: "sessions_history", group: "sessions", description: "Read session history.", paramsHint: "{ sessionKey? }", source: "builtin" },
29
- { name: "sessions_send", group: "sessions", description: "Send to another session.", paramsHint: "{ ... }", source: "builtin" },
30
- { name: "sessions_spawn", group: "sessions", description: "Spawn subagent session.", paramsHint: "{ prompt, ... }", source: "builtin" },
31
- { name: "session_status", group: "sessions", description: "Show current session status.", paramsHint: "{}", source: "builtin" },
32
- { name: "memory_search", group: "memory", description: "Search memory snippets.", paramsHint: "{ query }", source: "builtin" },
33
- { name: "memory_get", group: "memory", description: "Read memory entries.", paramsHint: "{ key }", source: "builtin" },
183
+ { name: "memory_get", group: "memory", description: "Read memory entries.", paramsHint: "{ key }", keywords: ["memory key", "stored context", "knowledge"], source: "builtin" },
34
184
  {
35
185
  name: "web_search",
36
186
  group: "web",
37
187
  description: "Search the web.",
38
188
  paramsHint: "{ query }",
39
- keywords: ["research", "discover", "find"],
189
+ keywords: ["discover", "find", "lookup", ...RESEARCH_KEYWORDS, ...REPORT_KEYWORDS],
40
190
  source: "builtin",
41
191
  },
42
192
  {
@@ -44,7 +194,7 @@ const BUILTIN: ToolEntry[] = [
44
194
  group: "web",
45
195
  description: "Fetch and extract web page content.",
46
196
  paramsHint: "{ url }",
47
- keywords: ["read page", "extract", "html"],
197
+ keywords: ["read page", "fetch url", "extract", "html", "article text", "content extraction", ...DATA_KEYWORDS, ...RESEARCH_KEYWORDS],
48
198
  source: "builtin",
49
199
  },
50
200
  {
@@ -52,14 +202,14 @@ const BUILTIN: ToolEntry[] = [
52
202
  group: "ui",
53
203
  description: "Browser automation.",
54
204
  paramsHint: "{ action, ... }",
55
- keywords: ["playwright", "stealth", "anti-bot", "captcha", "dynamic site", "javascript page"],
205
+ keywords: [...BROWSER_KEYWORDS, "web navigation", "click", "form fill", "screenshot", "scrape dynamic"],
56
206
  source: "builtin",
57
207
  },
58
- { name: "canvas", group: "ui", description: "Canvas/artifact rendering actions.", paramsHint: "{ action, ... }", source: "builtin" },
59
- { name: "cron", group: "automation", description: "Manage scheduled jobs.", paramsHint: "{ action, ... }", source: "builtin" },
60
- { name: "gateway", group: "automation", description: "Gateway control-plane actions.", paramsHint: "{ action, ... }", source: "builtin" },
61
- { name: "message", group: "messaging", description: "Message actions across channels.", paramsHint: "{ action, ... }", source: "builtin" },
62
- { name: "nodes", group: "nodes", description: "Invoke node-side capabilities.", paramsHint: "{ action, ... }", source: "builtin" },
208
+ { name: "canvas", group: "ui", description: "Canvas/artifact rendering actions.", paramsHint: "{ action, ... }", keywords: ["diagram", "visual", "chart", "artifact"], source: "builtin" },
209
+ { name: "cron", group: "automation", description: "Manage scheduled jobs.", paramsHint: "{ action, ... }", keywords: ["schedule", "recurring", "automation", "job timer"], source: "builtin" },
210
+ { name: "gateway", group: "automation", description: "Gateway control-plane actions.", paramsHint: "{ action, ... }", keywords: ["gateway control", "restart", "config patch", "service"], source: "builtin" },
211
+ { name: "message", group: "messaging", description: "Message actions across channels.", paramsHint: "{ action, ... }", keywords: ["notify", "chat", "post update", "send message"], source: "builtin" },
212
+ { name: "nodes", group: "nodes", description: "Invoke node-side capabilities.", paramsHint: "{ action, ... }", keywords: ["device", "camera", "screen", "location", "node action"], source: "builtin" },
63
213
  ];
64
214
 
65
215
  const GROUP_NAMES = new Set([
@@ -328,6 +478,10 @@ function score(query: string, entry: ToolEntry): number {
328
478
  const d = entry.description.toLowerCase();
329
479
  const g = entry.group.toLowerCase();
330
480
  const keywords = (entry.keywords ?? []).map((v) => v.toLowerCase());
481
+ const tokens = q
482
+ .split(/[^a-z0-9]+/)
483
+ .map((t) => t.trim())
484
+ .filter(Boolean);
331
485
 
332
486
  let s = 0;
333
487
  if (n === q) s += 100;
@@ -337,7 +491,7 @@ function score(query: string, entry: ToolEntry): number {
337
491
  if (d.includes(q)) s += 10;
338
492
  if (keywords.includes(q)) s += 25;
339
493
 
340
- for (const token of q.split(/\s+/).filter(Boolean)) {
494
+ for (const token of tokens) {
341
495
  if (n.includes(token)) s += 12;
342
496
  if (d.includes(token)) s += 4;
343
497
  if (g.includes(token)) s += 4;