feat(dynamic-tools-cache): 4 cache tools + global __padded API
Implements the openclaw side of Plexum decision #37: agent-driven per-session whitelist of which tools the model sees. Cross-runtime aligned with Plexum's host implementation (same tool names, same input schemas, takes-effect-next-turn). New surface: - tools/dynamic-tools-cache.ts: Catalog (in-memory map), Cache file (atomic tmp+rename at <openclaw>/agents/<id>/sessions/<sid>/dynamic-tools-cache.json), 4 tool factories (list/search/cache/evict), allowTool gate, installGlobalApi for globalThis.__padded with buffer-drain - index.ts: install __padded early; register the 4 cache tools as factories wrapping ctx into execute - openclaw.plugin.json contracts.tools += 4 names Other Hangman-Lab plugins (Fabric / HF / Dialectic) opt in to the gate by wrapping their registerTool calls (separate commits in those repos). Built-in openclaw tools and non-opt-in plugins remain always-on. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,13 @@ import {
|
||||
queueDynamicTrim,
|
||||
drainTrimQueueForSession,
|
||||
} from './tools/session-rewrite.js';
|
||||
import {
|
||||
installGlobalApi as installPaddedGlobalApi,
|
||||
createListToolsTool,
|
||||
createSearchToolsTool,
|
||||
createCacheToolsTool,
|
||||
createEvictToolsTool,
|
||||
} from './tools/dynamic-tools-cache.js';
|
||||
import {
|
||||
safeRestart,
|
||||
createSafeRestartTool,
|
||||
@@ -51,6 +58,12 @@ function register(api: OpenClawPluginApi): void {
|
||||
|
||||
logger.info('PaddedCell plugin initializing...');
|
||||
|
||||
// Install globalThis.__padded EARLY so other plugins loaded after
|
||||
// PaddedCell can register catalog entries / query allowTool. Plugins
|
||||
// loaded BEFORE PaddedCell can pre-fill _pendingCatalog on a stub;
|
||||
// installGlobalApi drains it.
|
||||
installPaddedGlobalApi();
|
||||
|
||||
const pluginConfig = getPluginConfig(api);
|
||||
const openclawPath = resolveOpenclawPath(pluginConfig as { openclawProfilePath?: string });
|
||||
const proxyAllowlist = resolveProxyAllowlist(pluginConfig as { proxyAllowlist?: unknown; 'proxy-allowlist'?: unknown });
|
||||
@@ -241,6 +254,27 @@ function register(api: OpenClawPluginApi): void {
|
||||
} as any;
|
||||
});
|
||||
|
||||
// dynamic-{list,search,cache,evict}-tools — per-session tools-cache
|
||||
// family (cross-runtime alignment with Plexum decision #37). All four
|
||||
// are essentials (always exposed). The cache they manage gates other
|
||||
// opt-in plugins via globalThis.__padded.allowTool — see
|
||||
// tools/dynamic-tools-cache.ts and plans/OPENCLAW_TOOLS_FILTER_HOOK.md.
|
||||
const cacheToolFactories = [
|
||||
createListToolsTool,
|
||||
createSearchToolsTool,
|
||||
createCacheToolsTool,
|
||||
createEvictToolsTool,
|
||||
];
|
||||
for (const make of cacheToolFactories) {
|
||||
api.registerTool((ctx) => {
|
||||
const tool = make();
|
||||
const inner = tool.execute;
|
||||
tool.execute = async (callId: string, params: any) =>
|
||||
inner(callId, params, { agentId: ctx.agentId, sessionId: ctx.sessionId });
|
||||
return tool;
|
||||
});
|
||||
}
|
||||
|
||||
// Register /ego-mgr slash command if the host exposes the (non-standard) hook.
|
||||
// This API is not part of the current OpenClawPluginApi surface; the guard
|
||||
// makes the plugin a no-op for slash commands when the host doesn't support
|
||||
|
||||
Reference in New Issue
Block a user